2

ARCがObjective-Cに来たとき、私はClangプロジェクトのWebサイトに投稿されたObjective-C自動参照カウント(ARC)ガイドを読んで、それが何であるかをよりよく理解するために最善を尽くしました。私がそこで見つけたのは(そして他のどこにもありません)、__attribute__特定のコードがその戻り値を自動解放するかどうか、たとえば(__attribute__((ns_returns_autoreleased)))、またはパラメーターを「消費する」かどうか(など)をARCに示すために宣言を使用することについての言及でし__attribute((ns_consumed))た。

しかし、ガイドはこれらの宣言が保持する実際の必要性のレベルについてほとんど何も述べていないようです。それらを除外しても、静的アナライザーを実行する場合でも、プロジェクト自体を実行する場合でも、違いはないようです。これらも違いを生むのでしょうか?メソッドにラベルを付けることに利点はあります__attribute__((objc_method_family(new)))か?私がARCで見つけた記事では、これらの指定子についてはまったく言及されていません。おそらく、ARCの第一人者は、これらが何に使用されているかについて語ることができます。

(個人的には、念のために関連するすべての指定子を含めますが、コードが難読化されて乱雑になることがわかります。)

4

3 に答える 3

5

これらの属性は、次のような異常な場合に明確に使用されます。

保持可能なオブジェクトポインタ型の関数またはメソッドパラメータは、消費済みとしてマークされる場合があります。これは、呼び出し先が+1保持カウントの所有権を取得することを期待していることを示します。

保持可能なオブジェクトポインタタイプを返す関数またはメソッドは、保持された値を返すものとしてマークされる場合があります。これは、呼び出し元が+1の保持カウントの所有権を取得することを期待していることを示します。

通常、これらのことを行うことはないため、通常、これらの属性を使用することはありません。属性がない場合、通常の動作(NARCルール、またはARCではCANと言うべきです)は、コンパイラーが実装および期待するものです。

これらの属性を使用する理由は2つあります。

  • CANルールに違反するため。つまり、参照を返すように名前が付けられていないメソッド、または参照を返さないように名前が付けられたメソッドを持つことです。属性は、メソッドのプロトタイプの違反を文書化し、実装でARCを使用している場合は、それを実装する必要がある場合もあります。
  • CoreGraphicsタイプを含むCoreFoundationタイプの操作。これらはARC化されていないため、ブリッジ属性を使用して、「保持可能なオブジェクトポインタ」タイプとの間の変換を支援する必要があります。
于 2011-10-01T18:12:36.737 に答える
3

LLVMとClangはObjCの命名規則を知っているので、ほとんどの場合、これは必要ありません。したがって、Cocoaの標準の命名規則に従う場合、LLVMは、対応するファミリ/リターンメモリポリシーに従うことを自動的に想定します。

つまり、その名前のメソッドを宣言すると、initWith...それは自動的に「init」ファミリーのメソッドと見なされ、指定する必要はありません__attribute__((objc_method_family(init)))。Clangはそれを自動的に検出します。new家族なども同じです。

実際、__attribute__Clangがそのようなケースを推測できない場合にのみ、指定子を使用する必要があります。これは、実際にはめったに発生しません(実際には、使用する必要はありませんでした)。または、命名規則を尊重しない場合に限ります。


Clang言語拡張機能のドキュメントの引用:

Objective-Cの多くのメソッドには、セレクターによって決定される従来の意味があります。静的分析の目的で、適切なセレクターがないにもかかわらず、特定の従来の意味を持つものとして、またはセレクターが示唆する従来の意味を持たないものとしてメソッドをマークできると便利な場合があります。これらのユースケースでは、メソッドが属するメソッドファミリーを具体的に説明する属性を提供します。

したがって、命名規則(常に行う必要があります)を尊重するとすぐに、何もする必要がなくなります。

于 2011-10-01T18:11:49.523 に答える
0

可能な限り、命名規則に固執する必要があります。

于 2011-10-14T19:12:05.810 に答える