为什么clang没有'n​​onnil'属性?

gri*_*eak 13 attributes objective-c clang

nonnull适用于C函数,但不适用于obj-c方法.要清楚,我建议这样做

- (void)doSomethingWithRequiredString:(NSString * __attribute((nonnil)))requiredString
                                  bar:(NSString *)optionalString);
Run Code Online (Sandbox Code Playgroud)

或者(更像是非空的)

- (void)doSomethingWithRequiredString:(NSString *)requiredString
                                  bar:(NSString *)optionalString)
__attribute((nonnil(0)));
Run Code Online (Sandbox Code Playgroud)

我对是否有一个很好的技术原因感到困惑.我知道clang只能真正使用该属性进行编译时检查或静态分析,但这似乎是正交的.是否有一些强有力的理由这样做?

Dav*_*ong 26

你完全可以.你做错的唯一事情就是认为方法参数是0索引的,而实际上它们是1索引的(哦,它nonnull不是nonnil):

- (void)doSomethingWithRequiredString:(NSString *)requiredString
                                  bar:(NSString *)optionalString
        __attribute((nonnull(1)));
Run Code Online (Sandbox Code Playgroud)

现在当你尝试使用它时:

id thing = ...;
[thing doSomethingWithRequiredString:nil bar:@"42"];
Run Code Online (Sandbox Code Playgroud)

Xcode将通过说"Null传递给需要非空参数的被调用者"来警告您.

此外,如果省略__attribute的"(1)"部分,则假定非零要求适用于所有参数.

Clang识别GCC属性,GCC对nonnull属性的定义如下:http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html#index-g_t_0040code_007bnonnull_007d-function-attribute-1733


更新:从Xcode 6.3开始,支持更清晰的语法.

在属性和方法中,关键字是nullable,nonnullnull_unspecified.

所以你的方法签名会变成这样:

- (void)doSomethingWithRequiredString:(nonnull NSString *)requiredString
                                  bar:(nullable NSString *)optionalString;
Run Code Online (Sandbox Code Playgroud)