ios 指针缺少可空性类型说明符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32539285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pointer is missing a nullability type specifier
提问by kelin
In Xcode 7 GM I started to get this warning:
在 Xcode 7 GM 中,我开始收到此警告:
Pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)
指针缺少可空性类型说明符(_Nonnull、_Nullable 或 _Null_unspecified)
In the following function declaration (NSUserDefaults extension)
在下面的函数声明中(NSUserDefaults 扩展)
- (void)setObject:(nullable id)value
forKey:(NSString *)defaultName
objectChanged:(void(^)(NSUserDefaults *userDefaults, id value))changeHandler
objectRamains:(void(^)(NSUserDefaults *userDefaults, id value))remainHandler;
Why this warning is showing and how should I fix it?
为什么会显示此警告,我该如何解决?
采纳答案by Ares
You need to specify nullable
also for the handlers/blocks
您还需要nullable
为处理程序/块指定
- (void)setObject:(nullable id)value
forKey:(nonnull NSString *)defaultName
objectChanged:(nullable void(^)(NSUserDefaults *userDefaults, id value))changeHandler
objectRamains:(nullable void(^)(NSUserDefaults *userDefaults, id value))remainHandler;
Why? It's due to Swift. Swift allows optional parameters (?), which Objective-C does not. This is done as a bridge between the both of them for the Swift compiler to know those parameters are optional. A 'Nonnull' will tell the Swift compiler that the argument is the required. A nullable that it is optional
为什么?这是由于斯威夫特。Swift 允许可选参数 (?),而 Objective-C 则不允许。这是作为两者之间的桥梁,以便 Swift 编译器知道这些参数是可选的。'Nonnull' 将告诉 Swift 编译器该参数是必需的。一个可空的,它是可选的
For more info read: https://developer.apple.com/swift/blog/?id=25
欲了解更多信息,请阅读:https: //developer.apple.com/swift/blog/?id=25
回答by Kevin
You can use the following macros around blocks of declarations (functions and variables) in objective c headers:
您可以在目标 c 标头中的声明块(函数和变量)周围使用以下宏:
NS_ASSUME_NONNULL_BEGIN
NS_ASSUME_NONNULL_END
You need to then add nullable annotations for references that can be nil within that block. This applies to both function parameters and variable declarations.
然后,您需要为该块中可能为零的引用添加可为空的注释。这适用于函数参数和变量声明。
As in:
如:
@interface SMLBaseUserDetailsVC : UIViewController < UICollectionViewDelegate>
NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) IBOutlet UIScrollView *detailsScrollView;
@property (nonatomic, readonly) IBOutlet UICollectionView *photoCV;
@property (nonatomic, weak, readonly) SMLUser *user;
- (IBAction)flagUser:(id)sender;
- (IBAction)closeAction:(nullable id)sender;
- (void) prefetchPhotos;
NS_ASSUME_NONNULL_END
@end
Edit* The why??? is because for an objective-c class to be interoperable with swift, you need to declare nullability so that the compiler knows to treat properties as swift optionals or not. Nullable objective c properties are known as optionals in swift and using these macros in conjunction with the nullable declarators for properties allows the compiler to treat them as optionals (Optionals are monads - an object that wraps up either the object or nil).
编辑* 为什么???是因为对于要与 swift 互操作的 Objective-c 类,您需要声明可空性,以便编译器知道是否将属性视为 swift 可选。可空的目标 c 属性在 swift 中被称为可选项,将这些宏与属性的可空声明符结合使用允许编译器将它们视为可选项(可选项是 monads - 一个包含对象或 nil 的对象)。
回答by kelin
The correct, working method declaration, accepted by compiler:
编译器接受的正确的工作方法声明:
- (void)setObject:(nullable id)value
forKey:(nonnull NSString *)defaultName
objectChanged:(nullable void(^)(NSUserDefaults *_Nonnull userDefaults, id _Nullable value))changeHandler
objectRamains:(nullable void(^)(NSUserDefaults *_Nonnull userDefaults, id _Nullable value))remainHandler;
回答by fishtrees
I post this answer to tell why should add _Nonnull
or nullable
.
我发布此答案是为了说明为什么要添加_Nonnull
或nullable
。
According to this blog: https://developer.apple.com/swift/blog/?id=25
根据这个博客:https: //developer.apple.com/swift/blog/?id=25
One of the great things about Swift is that it transparently interoperates with Objective-C code, both existing frameworks written in Objective-C and code in your app. However, in Swift there's a strong distinction between optional and non-optional references, e.g.
NSView
vs.NSView?
, while Objective-C represents boths of these two types asNSView *
. Because the Swift compiler can't be sure whether a particularNSView *
is optional or not, the type is brought into Swift as an implicitly unwrapped optional,NSView!
.
Swift 的一大优点是它可以与 Objective-C 代码透明地互操作,现有的框架都是用 Objective-C 编写的,也可以是你的应用程序中的代码。然而,在 Swift 中,可选引用和非可选引用之间有很大的区别,例如
NSView
vs.NSView?
,而 Objective-C 将这两种类型都表示为NSView *
. 因为 Swift 编译器不能确定一个特定的是否NSView *
是可选的,所以该类型作为一个隐式解包的可选NSView!
.
it's all for Swift.
这一切都是为了 Swift。
回答by Albert Renshaw
To disable this warning across your entire project
在整个项目中禁用此警告
Go to Build Settings
Make sure you are viewing the "All" tab not "Basic" or "Customized"
Search for the field
Other Warning Flags
Add the following flag:
-Wno-nullability-completeness
.Now clean and build (cmd+shift+k then cmd+r)
Quit xCode and Re-open (Don't skip this step!)
--note, it can take a few seconds for the warnings to go away even after you finish building and relaunching xCode, for me it takes about 15 seconds for xCode to fully update
转到构建设置
确保您查看的是“全部”选项卡,而不是“基本”或“自定义”
搜索领域
Other Warning Flags
添加以下标志:
-Wno-nullability-completeness
.现在清理并构建(cmd+shift+k 然后 cmd+r)
退出 xCode 并重新打开(不要跳过这一步!)
--注意,即使在您完成构建和重新启动 xCode 后,警告消失也可能需要几秒钟,对我而言,xCode 完全更新需要大约 15 秒
回答by dilip
Remove below macro from your .h file and warning will disappear
从您的 .h 文件中删除以下宏,警告将消失
NS_ASSUME_NONNULL_BEGIN
NS_ASSUME_NONNULL_END