【问题标题】:Pointer is missing a nullability type specifier in autogenerated ModuleName-Swift.h file指针在自动生成的 ModuleName-Swift.h 文件中缺少可空性类型说明符
【发布时间】:2018-09-26 04:17:36
【问题描述】:

我有一个带有 swift 和 ObjC 源的项目,并且在自动生成的头文件中有一条奇怪的消息:

标有错误的代码:

//interface in ModuleName-Swift.h  file
@interface PointsList : NSObject
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
- (nonnull instancetype)initWithPoints:(NSArray<NSValue *> * /*this marked with warning*/_Nonnull)points OBJC_DESIGNATED_INITIALIZER; //Warning:Pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)
- (nonnull instancetype)initWithValues:(NSArray<NSValue *> * /*this marked with warning*/_Nonnull)pointValues //Warning:Pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)
@end



//source PointsList.swift
   @objc public class PointsList : NSObject {

    var points = Array<CGPoint>()
    @objc public override init() {
        super.init()
    }
    @objc public init(withPoints points: Array<CGPoint>) {
        self.points.append(contentsOf: points)
        super.init()
    }
    @objc public init(withValues pointValues: Array<NSValue>) {
        super.init()
        pointValues.forEach { (pointValue) in
                self.points.append(pointValue.cgPointValue)
        }
    }
}

这个文件是由 Xcode 从 swift 的类中生成的。我看到 _Nunnull 修饰符,但 XCode 抱怨我应该添加该修饰符 .也许我忘记了项目配置中的一些设置。
我该如何解决这种奇怪的行为?

UPD
我对 Swift 5 和 Xcode 10.2 有同样的问题。
这很奇怪,因为我项目中的其他文件都以正确的方式处理。
只有 _Nonnull_Nullable 修饰符有问题。 Xcode 忽略它们,如果我在警告消息中按下按钮 Fix,Xcode 会在指针上添加第二个修饰符并且警告不会消失。

【问题讨论】:

  • 如果您将相关代码作为文本发布到您的问题中,这将非常有帮助。
  • 我已经更新了我的问题。我添加了产生该警告的生成接口和源类的示例。
  • 似乎是编译器问题。您尝试过干净的构建吗?
  • 是的。没有变化。我在 Xcode 9 和 Xcode 10 中遇到了同样的问题 :(
  • 好像少了什么,Swift代码没有编译(self.points未定义)

标签: objective-c swift xcode


【解决方案1】:

在纯 ObjC 中,您实际上不需要使用 _Nullable_Nonnull。这些调用比nullablenonull 低级调用,仅在执行C++ 操作(如typedef 和块)时才需要。

真的,您也不应该使用nonnull。我通常使用的唯一标识符是nullable。这样做的原因是你应该在你的 ObjC 代码中使用 NS_ASSUME_NONNULL_BEGIN/NS_ASSUME_NONNULL_END 包装器,这不仅是为了可读性,而且是为了更详细的编译器警告/错误和更好的 Swift 互操作性。

建议编写类似这样的 ObjC 类:

// SomeClass.h

NS_ASSUME_NONNULL_BEGIN
@interface SomeClass : NSObject
-(instancetype)initWithRequiredSomething:(NSString *)requiredString optionalSomething:(nullable NSString *)optionalString;
@end
NS_ASSUME_NONNULL_END

返回值和requiredString都隐含nonnulloptionalStringnullable

尝试检查您的项目并删除_Nullable_Nonnullnonnull 的所有实例,您可能会发现它非常令人满意(并希望解决问题!)。

【讨论】:

  • 问题不在于 ObjC 类,而是为 swift 类生成的接口问题。在 ObjC 类中,我使用 NS_ASSUME_NONNULL_BEGIN/END 和可为空的修饰符。如果您注意我添加的代码中的 cmets,您会看到生成的接口中存在警告。我在其他项目中也没有同样的问题。这是一个非常古老的项目(从 Xcode 4 开始)。
  • 您上面的评论说“如果我尝试使用 _Nonnull 修饰符,Xcode 会抱怨”,这听起来像是您在手动添加_Nonnull。不是这样吗?
  • 我认为这是项目中的全局问题,而不仅仅是生成的文件中。我试图找到 C 函数的可空性标记但找不到它(xCode 向所有标记抱怨,但不应该向 _Nonnull、_Nullable 抱怨)。此外,我不能在块的参数中使用“可为空”,因为块是 C 的一部分,而不是 Objective-C。主要问题只出在生成的文件上,编译后在文件中看到>>300警告,不是很好,因为我可以丢失其他文件中的重要警告。
  • 当 NS_ASSUME_NONULL_BEGIN 缺少匹配的 _END 时,我也看到过类似的问题。通过搜索确认您拥有相同数量的每个标识符
  • 我已经检查过了,我有 245 个 BEGIN 和 245 个 END。我还检查了开始后的结尾,一切都正确。 :( .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-21
相关资源
最近更新 更多