18

私は一般的にiOS開発に不慣れで、手動の参照カウント(保持、リリース、自動解放)を扱ったことはありません。そのため、魔法の ARC が何を行っているのかよくわかりません。

次のようなオブジェクトを指す読み取り専用プロパティにどのタイプの所有権 ( weakstrong、など) を付与する必要があるかを尋ねられるまで、私は理解していると思っていました。assign

@property (readonly,nonatomic) NSString* name;

ここで読んだ ARC の読み取り専用の @property に関する質問でstrong、 /をオフにすると、プロパティのweakときにバッキング変数を指定しない限り、実際にはコンパイルされません。@synthesizeたまたま、次のようにバッキング ivar を指定していました。

@synthesize name = _name;

ここから、変数のデフォルトの「ライフタイム修飾子」が強力であることを理解しました:http://developer.apple.com/library/ios/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html#//apple_ref /doc/uid/TP40011226-CH1-SW4

つまり、簡単に言えば(readonly,nonatomic,strong)_nameivar が暗黙的に として宣言されているため、間接的に自分のプロパティを として定義しています__strong

いくつかの質問を聞きたいんです:

  1. strong使用する正しい有効期間修飾子はありますか? そうでないと、オブジェクトのバッキングはNSString*どこにも所有されず、自動的に解放されます (Java ランドから来ると、デフォルトですべての参照が強いため、これは理にかなっています)。

  2. またはなど、この状況で意味のある他の修飾子はありますcopyassign?

  3. プロパティを次のように宣言すると、プロパティ(readonly,nonatomic,strong)使用する(readonly,nonatomic)コードに違いが生じますか? 例えば。キーワードなしで宣言すると、プロパティがポインターに格納される場所としてオブジェクトポインターが格納されますか?strong__unsafe_unretainedstrong__strong

ありがとう!

編集

したがって、私が理解しているように、読み取り専用プロパティには次のことが当てはまります。

  • 非 NSObject* タイプ (int、float、void* など) の場合は、 を使用します(readonly, assign)
  • オブジェクト ポインターの場合、(readonly, strong)or (readonly, copy)- これらの機能は読み取り専用プロパティと同じですが、プロパティを として拡張/サブクラス化して再宣言する場合は、コピー セマンティクスが必要になる場合がありますreadwrite
  • オブジェクト ポインターの(readonly, weak)場合、そのプロパティに既に弱いポインターを格納する場合にのみ意味があります (そのポインターは他の場所で強い必要があります。そうしないと、オブジェクトの割り当てが解除されます)。
4

3 に答える 3

12
  1. strongあなたが指しているものが何であれ、強力な(所有する)参照を保持したい場合に使用するのが正しいです。通常、強い参照が必要ですが、循環参照を防ぐために (特に、親が子を指し、子が親を指している場合、それらが決して解放されない親子関係では)、弱い参照を使用する必要がある場合があります。 . また、所有していないオブジェクトへのポインターを保持したいが、それが存在する限り有効にしたい場合は、弱いポインターを使用する必要があります。自動的に設定されnil、本来あるべきではないメモリを指すことはありません。

  2. assignスカラー値で使用され、デフォルトのセッターです。 copyオブジェクトのコピーを自動的に作成し、ポインタを元のオブジェクトではなくそのコピーに設定する場合に適しています。特定の必要性がある場合にのみ、これを行うのが理にかなっています (通常は、オブジェクトが自分で変化することを望まないため)。

  3. __strong がデフォルトであることを示す提供したリンク(したがって、指定する必要はありません)は、変数を参照し、宣言されたプロパティを参照しません。宣言されたプロパティのデフォルトは であるため、確かに違いがあります。ただし、必要な場合は、指定しても指定しなくても違いはありません (それがあなたが望んでいたものであることを明確にすることを除いて)。 編集:ただし、Jacques が指摘したように、これは LLVM 3.1 で変更されており、デフォルトはからに変更されています。この場合、指定しても指定しなくてもまったく違いはありませんassignassignassignstrongstrong必要に応じて省略できます。個人的には、コードを見ているすべての人が同じページにいるように (特に異なるバージョン間で競合があるため) スペルアウトするのは良いことだと思います。ただし、他の人はこの点に同意しないかもしれません。:)

ここで、Objective-C プログラミング言語の宣言されたプロパティのセクションを読むことをお勧めします。<document removed by Apple with no direct replacement>

于 2012-05-22T01:41:10.303 に答える
7

追加ポイント: プロパティは からreadonlyに再宣言できますreadwrite。たとえば、サブクラスはスーパークラスの読み取り専用プロパティを読み書き可能にすることができます。これは、多くの Cocoa クラスに可変性を追加するサブクラスがあるのと同様です。同様に、プロパティはパブリックに読み取り専用である場合がありますが、クラスはクラス拡張で内部使用するために読み書き可能に再宣言する場合があります。そのため、クラスが独自のプロパティを設定する場合、メモリ管理を適切に行い、適切な Key-Value Observing 変更通知を発行する合成セッターを利用できます。

現状では、プロパティの他のすべての属性は一貫している必要があります。コンパイラがこの要件を緩和できる可能性があります。(バグだと考える人もいます。) いずれにせよ、これが、、または weakreadonlyのような所有権属性を持つプロパティを宣言する理由の 1 つです。strongcopyreadwrite

質問 3 に関して、所有権修飾子がゲッターを呼び出すコードに影響するかどうかを尋ねていますか? いいえ、そうではありません。

于 2012-05-22T03:54:18.370 に答える
0

これらの2行のコードは私にとってはうまくいきます:

.h ファイル:

@property (nonatomic, readonly, copy) NSString *username;

.m ファイル:

@property (nonatomic, readwrite, copy) NSString *username;
于 2015-08-21T19:45:23.437 に答える