オブジェクトを「自動解放」してメソッドから返す場合、オブジェクトを再調整するメソッドを呼び出す「親メソッド」でオブジェクトを「解放」する必要がありますか?
いいえ、その理由は次のとおりです。あなたが言った通りに例をレイアウトしましょう:
-(NSObject*)someMethodThatReturnsAnAutoreleasedObject {
return [[[NSObject alloc]init]autorelease];
}
-(void)myMethod {
NSObject *obj = [self someMethodThatReturnsAnAutoreleasedObject];
[obj doSomething];
[obj release] //PROBLEM!
}
オブジェクトの保持数を段階的に見ていくと、-autorelease
すぐには問題が発生しないかもしれませんが、後日問題が発生することがわかります(-autorelease
オブジェクトは「自動解放」されないため)。所有しているプールが空になるか、割り当てが解除されると、それらはまとめて割り当て解除されます)。自動解放されたオブジェクトを返すメソッドは、最終的に保持カウントが0(0(開始)+ 1(割り当て)-1(自動解放))でオブジェクトを返すため、解放する必要がないだけでなく、クラッシュが発生します。
2番目の質問は、メソッド(別のオブジェクトのインスタンスメソッドfe userService)からオブジェクト(fe user)を返し、それをプロパティ(self.userProp、オブジェクトuserServiceを自己インスタンス化して彼のメソッドを呼び出した)に保存したことです。オブジェクトuserService(メソッドがオブジェクトuserを返し、プロパティself.userPropに格納されている)を解放すると、プロパティに格納されているオブジェクト(プロパティself.userPropに格納されているオブジェクトuser)も解放されました。なんで?プロパティ内のオブジェクトの所有者は誰でしたか?
繰り返しになりますが、最初に少しセットアップします(これは最初はかなり複雑ですが、何をしているのかを確認した後は完全に理にかなっています)。
-(NSUserService*)someMethodThatReturnsAnAutoreleasedObject {
return [[[NSUserService alloc]init]autorelease];
}
-(void)myMethod {
self.userservice = [self someMethodThatReturnsAnAutoreleasedObject];
[obj doSomething];
[obj release] //No problem, assuming userService is declared retain or strong.
}
さて、なぜこれが違うのですか?メモリ修飾子、それが理由です!プロパティを宣言するときは、メモリ修飾子のセットを宣言して、割り当て記号に追加する修飾子の種類をコンパイラーに指示します。ほとんどのプロパティは、オブジェクトタイプである場合、宣言されているretain
か強力です((ARCの下で)、できれば、プロパティもuserService
そのように宣言されていることを願っています)。これにより、コンパイラは解釈します。
self.userservice = [self someMethodThatReturnsAnAutoreleasedObject];
なので
self.userservice = [[self someMethodThatReturnsAnAutoreleasedObject]retain];
したがって、リリースする必要があります。そうしないと、手にリークが発生します(0(開始)+ 1(割り当て)-1(自動リリース)+ 1(保持)= +1)。