指针缺less可以为空的types说明符
在Xcode 7 GM中,我开始得到这个警告:
指针缺less一个可空types说明符(_Nonnull,_Nullable或_Null_unspecified)
在下面的函数声明(NSUserDefaults扩展)
- (void)setObject:(nullable id)value forKey:(NSString *)defaultName objectChanged:(void(^)(NSUserDefaults *userDefaults, id value))changeHandler objectRamains:(void(^)(NSUserDefaults *userDefaults, id value))remainHandler;
为什么这个警告正在显示,我该如何解决?
您还需要为处理程序/块指定nullable
为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;
为什么? 这是由于斯威夫特。 Swift允许可选的参数(?),而Objective-C没有。 这是作为Swift编译器之间的桥梁,以了解这些参数是可选的。 “Nonnull”会告诉Swift编译器该参数是必需的。 可以为空,它是可选的
欲了解更多信息,请阅读: https : //developer.apple.com/swift/blog/?id = 25
您可以在目标c头文件中的声明(函数和variables)块周围使用以下macros:
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END
然后,您需要添加可为null的注释,以便在该块中可以为零。 这适用于函数参数和variables声明。
如:
@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
编辑*为什么? 是因为对于一个Objective-C类可以与swift进行交互操作的,你需要声明为空,以便编译器知道把属性当作swift optionals。 可空目标的c属性在swift中被称为可选项,将这些macros与可为空的声明符用于属性允许编译器将它们视为可选项(可选属性是monad – 包装对象或nil的对象)。
编译器接受的正确的工作方法声明:
- (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;
我发布这个答案告诉为什么要添加_Nonnull
或nullable
。
根据这个博客: https : //developer.apple.com/swift/blog/?id = 25
Swift最伟大的事情之一就是它可以与Objective-C代码透明地互操作,Objective-C中编写的现有框架以及应用程序中的代码。 然而,在Swift中,可选的和非可选的引用有很大的区别,例如
NSView
和NSView?
而Objective-C则将这两种types都表示为NSView *
。 因为Swift编译器不能确定一个特定的NSView *
是否是可选的,所以这个types被作为隐式解包的NSView!
。
这一切都是为了Swift。