NSString オブジェクトが引数として渡された場合、常に次のことを行う必要がretain
ありrelease
ます。
-forExample:(NSString*)str{
[str retain];
//do something
[str release];
}
か否か?これはいつ、どこで使用すればよいですか?
NSString オブジェクトが引数として渡された場合、常に次のことを行う必要がretain
ありrelease
ます。
-forExample:(NSString*)str{
[str retain];
//do something
[str release];
}
か否か?これはいつ、どこで使用すればよいですか?
そのオブジェクトの参照カウントは、このメソッドの過程で変化しないため、送信する理由はありませんretain
。Apple のMemory Management エッセイから(必ず目を通すべきです):
プログラムの他の場所からオブジェクトを受け取った場合、通常は、受け取ったメソッドまたは関数内で有効であることが保証されています。その範囲を超えて有効であり続けたい場合は、それを保持またはコピーする必要があります。既に割り当てが解除されているオブジェクトを解放しようとすると、プログラムがクラッシュします。
現在のスコープを超えてオブジェクトを保持する必要がある場合にのみ、オブジェクトを保持する必要があります。
- (void) forExample: (NSString *)theString {
// Will need this object later. Stuff it into an ivar and retain it.
// myString = [theString retain];
// For NSString, it's actually better to copy, because this
// could be a _mutable_ string, and it would in fact be best to use
// the setter for the ivar, which should deal with the memory management:
[self setMyString:theString];
// Do things...
// Don't release.
}
オブジェクトを保持している場合は、不要になったrelease
ときに送信する必要があります。
- (void) otherExample {
[myString doYourStringThing];
// If you don't need the string past this point (which would be slightly
// unusual -- it leaves an ivar unset) release it and set it to nil.
// [myString release]; myString = nil;
// Again, it would be best to use the setter:
[self setMyString:nil];
}
// Generally you keep ivars around until the instance is deallocated,
// and release them in dealloc
- (void) dealloc {
[myString release];
[super dealloc];
}
優れた開発者のように、Objective-C の最新のトレンドに遅れずについていき、自動参照カウントを使用しているため、どちらも行うべきではありません。自動参照カウントにより、retain/release を手動で呼び出す必要がなくなり、LLVM 3.0 および Xcode 4.2 に付属しています。
なんらかの理由で、ここで行っているように手動のメモリ管理を使用したい場合は、ほとんどの場合、手動でretain
andを呼び出すべきではありません。release
通常、すべての引数を個別に保持する必要はなく、自分の判断で問題ありません。
これが良い考えとなる唯一のケースは、ある時点でメソッドがコールバックを呼び出すか、引数を使用する前に解放する可能性のある何かを呼び出す場合です。これは、たとえば、関数がブロックを受け取り、その実行中にそのブロックを呼び出す場合に当てはまります。そのブロックが引数として渡されたオブジェクトを解放し、ブロックの呼び出し後にそのオブジェクトを使用する場合、引数は本質的にダングリング ポインターです。
そのようなシナリオの例:
- (void)myFunction:(NSString *)foo block:(void (^)())callback {
[foo retain];
callback();
// .. do some stuff
[foo release];
}
- (void)myCallingFunction {
NSString * myVariable = [[NSString alloc] initWithString:@"Test"];
[self myFunction:myVariable block:^ {
[myVariable release];
}];
}
ご覧のとおり、コードはコメント[myVariable release]
の前に到達します。// .. do some stuff