ARCでPersonクラスを定義する場合、
- イニシャライザでself.fullnameまたは単にfullnameを使用する必要がありますか?
- フルネームを使用した場合、渡された文字列は保持されますか?
- self.fullnameを使用する場合、セッターまたはプロパティを定義する必要がありますか?強く使うべきですか?
ARC以前の考え方から来て、私はARCが提案する変更に頭を悩ませようとしています。
ARCでPersonクラスを定義する場合、
ARC以前の考え方から来て、私はARCが提案する変更に頭を悩ませようとしています。
self.fullname
ARCでは、セッターを通過することを除いて、これらは同じように動作します。デフォルトのセッターは、KVO準拠を提供します。しかし、それ以外の点では違いはありません。self.fullname = ...
するには、セッターを定義する必要があります。NSStringや、可変バリアントを持つ他のクラスの場合、通常はを使用することをお勧めします(copy)
。初期化子では、オブジェクトが自己無撞着性を欠く異常な状態にあるため、でメソッドを呼び出さないことをお勧めします。self
あなたが与える簡単な例では、それはすぐには違いがありません。-setFullname:
ただし、後でオブジェクトの他の部分を読み書きする独自のメソッドを定義する場合self.fullname =
、オブジェクトがまだ完全に形成されていないため、初期化子から呼び出すと問題が発生します。
利用可能な回答には、いくつかの説明が必要だと思います。
このヘッダーを見てください:
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;
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