いくつかの考え:
ベスト プラクティスは、自動的に合成されたアクセサー メソッドを利用するために、セッターをまったく作成しないことです)。独自のものを作成することは、メモリ管理を台無しにしたり、バグを導入したりする機会にすぎません。カスタム セッターを作成する前に、どうしてもカスタム セッターが必要である必要があります。
インスタンス変数名の新たな慣例は、先頭にアンダースコアを付けたプロパティ名を使用することです (たとえば、 というプロパティname
の場合、ivar は です_name
)。このステートメントを省略した場合@synthesize
、最近のバージョンの Xcode に含まれているコンパイラがこれを自動的に行います。
セッターがどうあるべきかという問題は、プロパティにどのようなメモリ修飾子があったかを述べていなければ意味がありません。プロパティを として定義したと仮定しますretain
。
プロパティを a にNSMutableString
変更すると、プロパティの動作が変更されます。何らかの理由で変更可能な文字列が本当に必要でない限り、お勧めしません。
誰かがname
プロパティを に設定した場合、最初の例は何もしませんnil
。しかし、誰かがそれを に設定したい場合でも、(a) 古い値をnil
解放する必要があります。name
(b) ivar を に設定しますnil
。(ちなみに、以下の私のコードは、nil
オブジェクトにメッセージを送信しても何も起こらないという事実を利用しているためnil
、この場合、メッセージがオブジェクトに送信されているかどうかを確認する必要はありません。)
したがって、次のように定義されたプロパティがあると仮定します。
@property (nonatomic, retain) NSString *name;
そして、省略されているか次のような合成行があります。
@synthesize name = _name;
次に、セッターは次のようになると思います。
-(void) setName:(NSString *)name
{
// if you want to program defensively, you might want the following assert statement:
//
// NSAssert(name == nil || [name isKindOfClass:[NSString class]], @"%s: name is not string", __FUNCTION__);
if (name != _name)
{
[_name release];
_name = name;
[_name retain];
}
}
ちなみに、あなたのinit
メソッドが適切に初期化さ_name
れ、それdealloc
が解放されると仮定します。
- (id)init
{
self = [super init];
if (self) {
_name = nil;
}
return self;
}
- (void)dealloc
{
[_name release];
[super dealloc];
}
bblum が指摘しているように、プロパティに使用するのが賢明copy
ですNSString
。
@property (nonatomic, copy) NSString *name;
次に、セッターは次のようになると思います。
-(void) setName:(NSString *)name
{
// if you want to program defensively, you might want the following assert statement:
//
// NSAssert(name == nil || [name isKindOfClass:[NSString class]], @"%s: name is not string", __FUNCTION__);
if (name != _name)
{
[_name release];
_name = [name copy];
}
}
しかし実際には、どうしても必要な場合を除き、セッターを作成するべきではありません。
最後に、コードには、メモリ管理がわかりにくいというコメントがあります。必ず理解する必要がありますが、最後に 2 つの提案をします。
自動参照カウント(ARC) の使用を検討してください。これにより、メモリ管理がどのように機能するかを理解する必要がなくなるわけではありませんが (『Advanced Memory Management Programming Guide』を参照)、メモリ管理を適切に処理するコードを簡単に記述できるようになります。手動参照カウント (MRC) コードを作成すると、単純なメモリ管理ミスが非常に発生しやすくなります。通常は ARC が対処します。
特に MRC を使用する場合は、Xcode の静的アナライザーを利用してください (「製品」メニューの「分析」またはshift+ command+を押しますB)。これにより、MRC コードを悩ませている多くの日常的なメモリ管理の問題を簡単に見つけることができます。Instruments User GuideのFinding Memory Leaksセクションには、コードのデバッグ中にリークを見つける方法も示されていますが、多くの場合、スタティック アナライザーはコードを調べるだけで問題を特定できます。