2013-10-04 13 views
13

nonnullは、C関数では機能しますが、obj-cメソッドでは機能しません。明確にするために、私はなぜclangに 'nonnil'属性がないのですか?

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

私は良い技術的な理由があるかどうかの上に困惑している(非NULLのようなより)この

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

かを示唆しています。私は、clangがコンパイル時のチェックや静的な解析に本当に属性を使うことができると理解していますが、それは直交しているようです。いくつかの理由がありますかではなく、ですか?

+0

私の疑惑を: 'clang'は、巨大なプロジェクトです。その開発者はより良いことをする。 –

答えて

26

あなたは完全にできます。

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

を今あなたがしようとする:あなたは間違ってやっている唯一のことは、実際には、彼らが1インデックスしているとき、そのメソッドのパラメータは、0インデックスされている(ああ、それはnonnilを、nonnullだではない)を考えています

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

Xcodeは、「null以外の引数を必要とする呼び出し先にNullが渡されました」と警告します。

また、__attributeの "(1)"部分を省略すると、非ゼロの要件がすべてのパラメータに適用されるものとみなされます。

はクランは、GCCの属性を認識し、nonnull属性のGCCの定義はここにある: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です。

だからあなたのメソッドのシグネチャは、このなる:Xcodeの6.3ベータ版で

- (void)doSomethingWithRequiredString:(nonnull NSString *)requiredString 
            bar:(nullable NSString *)optionalString; 
+0

多くのありがとう。それは私を得たインデックス作成でした。それは予想外でした。 – griotspeak

+0

@griotspeakええ、それもループのために私を投げた。 –

+0

@DaveDeLongには、この属性のパラメータ単位の方が簡単です。これは '__unused'に似ていますか? – danyowdee