13

nonnull适用于 C 函数,但不适用于 obj-c 方法。为了清楚起见,我建议这样做

- (void)doSomethingWithRequiredString:(NSString * __attribute((nonnil)))requiredString
                                  bar:(NSString *)optionalString);

或(更像非空)

- (void)doSomethingWithRequiredString:(NSString *)requiredString
                                  bar:(NSString *)optionalString)
__attribute((nonnil(0)));

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

4

3 回答 3

26

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

- (void)doSomethingWithRequiredString:(NSString *)requiredString
                                  bar:(NSString *)optionalString
        __attribute((nonnull(1)));

现在,当您尝试使用它时:

id thing = ...;
[thing doSomethingWithRequiredString:nil bar:@"42"];

Xcode 会通过说“Null 传递给需要非空参数的被调用者”来警告您。

此外,如果您省略 __attribute 的“(1)”部分,则假定非 nil 要求适用于所有参数。

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;
于 2013-10-04T16:29:17.000 回答
0

在 Xcode 6.3 beta 中,添加了新的 Objective-C 功能以在标头中表达(非)可空性:https ://developer.apple.com/swift/blog/?id=22

于 2015-02-14T07:53:05.370 回答
0

就在这里。

你可以这样编码:

- (nullable AAPLListItem *)itemWithName:(nonnull NSString *)name;
- (NSInteger)indexOfItem:(nonnull AAPLListItem *)item;

https://developer.apple.com/swift/blog/?id=25

于 2015-05-06T02:50:32.903 回答