借助Xcode 6.3,引入了新的注释,以便在 Objective-C 中更好地表达API的意图(当然,并确保更好的Swift支持)。这些注释当然是nonnull
,nullable
和null_unspecified
。
但是使用Xcode 7时,会出现很多警告,例如:
除此之外,Apple使用另一种可空性说明符,标记其C代码(source):CFArrayRef __nonnull CFArrayCreate(
CFAllocatorRef __nullable allocator, const void * __nonnull * __nullable values, CFIndex numValues, const CFArrayCallBacks * __nullable callBacks);
因此,总而言之,我们现在有以下3种不同的可空性注释:
nonnull
,nullable
,null_unspecified
_Nonnull
,_Nullable
,_Null_unspecified
__nonnull
,__nullable
,__null_unspecified
即使我知道为什么以及在何处使用哪种注释,我还是对应该使用哪种类型的注释,地点和原因感到困惑。这是我可以收集的:
nonnull
,nullable
和null_unspecified
。 nonnull
,nullable
和null_unspecified
。 __nonnull
,__nullable
和__null_unspecified
。 _Nonnull
,_Nullable
和_Null_unspecified
。 但是对于为什么我们有这么多基本上执行相同操作的注释,我仍然感到困惑。
所以我的问题是:
这些注释之间的确切区别是什么,如何正确放置它们以及为什么?
最佳答案
从clang
documentation:
, 和
因此,对于方法返回和参数,您可以使用
带双下划线的版本__nonnull
/__nullable
/__null_unspecified
,而不是单下划线版本或非下划线版本。 所不同的是,必须在类型定义之后放置单划线和双下划线的内容,而在类型定义之前放置非下划线的内容。
因此,以下声明是等效的并且是正确的:
- (nullable NSNumber *)result
- (NSNumber * __nullable)result
- (NSNumber * _Nullable)result
对于参数:
- (void)doSomethingWithString:(nullable NSString *)str
- (void)doSomethingWithString:(NSString * _Nullable)str
- (void)doSomethingWithString:(NSString * __nullable)str
对于属性:
@property(nullable) NSNumber *status
@property NSNumber *__nullable status
@property NSNumber * _Nullable status
但是,当涉及到双指针或块返回的结果与void不同时,事情就变得复杂了,因为这里不允许使用非下划线:
- (void)compute:(NSError * _Nullable * _Nullable)error
- (void)compute:(NSError * __nullable * _Null_unspecified)error;
// and all other combinations
与将块作为参数的方法类似,请注意,
nonnull
/nullable
限定符适用于块,而不适用于其返回类型,因此以下内容是等效的:- (void)executeWithCompletion:(nullable void (^)())handler
- (void)executeWithCompletion:(void (^ _Nullable)())handler
- (void)executeWithCompletion:(void (^ __nullable)())handler
如果该块具有返回值,那么您将被迫进入下划线版本之一:
- (void)convertObject:(nullable id __nonnull (^)(nullable id obj))handler
- (void)convertObject:(id __nonnull (^ _Nullable)())handler
- (void)convertObject:(id _Nonnull (^ __nullable)())handler
// the method accepts a nullable block that returns a nonnull value
// there are some more combinations here, you get the idea
结论是,只要编译器可以确定要向其分配限定符的项目,就可以使用任一个。
关于objective-c - Objective-C中可为空,__ nullable和_Nullable之间的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32452889/