1

ARCでPersonクラスを定義する場合、

  1. イニシャライザでself.fullnameまたは単にfullnameを使用する必要がありますか?
  2. フルネームを使用した場合、渡された文字列は保持されますか?
  3. self.fullnameを使用する場合、セッターまたはプロパティを定義する必要がありますか?強く使うべきですか?

個人クラス初期化子

ARC以前の考え方から来て、私はARCが提案する変更に頭を悩ませようとしています。

4

3 に答える 3

3
  1. self.fullnameARCでは、セッターを通過することを除いて、これらは同じように動作します。デフォルトのセッターは、KVO準拠を提供します。しかし、それ以外の点では違いはありません。
  2. はい、ポインタが強力であると宣言されていれば、そうなります。
  3. 使用self.fullname = ...するには、セッターを定義する必要があります。NSStringや、可変バリアントを持つ他のクラスの場合、通常はを使用することをお勧めします(copy)
于 2012-07-28T18:34:19.730 に答える
2

初期化子では、オブジェクトが自己無撞着性を欠く異常な状態にあるため、でメソッドを呼び出さないことをお勧めします。selfあなたが与える簡単な例では、それはすぐには違いがありません。-setFullname:ただし、後でオブジェクトの他の部分を読み書きする独自のメソッドを定義する場合self.fullname =、オブジェクトがまだ完全に形成されていないため、初期化子から呼び出すと問題が発生します。

于 2012-07-28T19:05:50.823 に答える
2

利用可能な回答には、いくつかの説明が必要だと思います。

あなたの質問に対する長い答え

このヘッダーを見てください:

Person : NSObject {
    NSString *name; // better to call this _name to not confuse it with the property
    // and even more better to not use an ivar, but only a property
}

@property (strong) NSString *name;
  1. インスタンス変数があります。通常、ivarはアンダースコア付きのプロパティと同じ名前で呼ばれますが、多くの場合、ivarとプロパティの名前は同じです。
  2. プロパティのみを宣言することも可能です。この場合、コンパイラはアンダースコア付きのivarを自動的に挿入します。

name = @"John Smith"ここで、との間に1つの大きな違いがあることを理解することが重要ですself.name = @"John Smith"。最初の変数は、インスタンス変数を直接設定します(つまり、_name = @"John Smith"メモリ管理を無視し、前の値がnilでない場合は、(ARCなしで)リークを作成します。 dot-syntax(self.name)は、自動的に生成されたアクセサー(= setterメソッド)を使用します。これは、選択されたメモリ管理(通常、保持、強力、またはコピー)を尊重します。

プロパティの前とARCの前では、オブジェクトセッターは次のようになります。

-(void)setName:(NSString*)newName {
    if(newName != name) {
        [name release];
        name = newName;
        [newName retain];
    }
}

つまり、古いiVar値が解放され、新しいiVar値が保持されます。すべてバランスが取れており、問題ありません。

現在、ARCと合成アクセサー(プロパティ)を使用すると、これらすべてを気にする必要はありません。プロパティはアクセサーを合成しますが、ARCはコードの分析に基づいて保持/解放呼び出しを合成し、バランスを取ります。したがって、ARCとプロパティは、異なる側面を合成するため、必ずしも相互に必要ではありません(たとえば、ivar宣言での構文「__weak」とプロパティ宣言での「(weak)」の構文が異なることに注意してください)。ただし、以前はどのように機能していたかを知っておくと便利です。これで、

name = @"John Smith"; // directly access ivar, the old value is never released 
// your program is leaking if you're not using ARC

合成されたアクセサーを通過します

self.name = @"John Smith"; // old ivar released, new ivar set, all okay

あなたの質問への短い答え

  1. 両方が必要ない場合は、ivarプロパティを使用しないでください
  2. self.property = newValueは、setterメソッドによって新しい値を設定します
  3. ivar = newValueは、setterメソッドをバイパスして、新しい値を直接設定します
  4. セッターメソッドがある場合は、アクセサーを使用し、ivarを直接設定しないことを強くお勧めします(つまり、プロパティがある場合は、self.property = newValueを呼び出してセッターを使用します)
于 2012-07-28T19:35:19.640 に答える