0

GC を使用しない非 ARC プロジェクトでのメモリ管理について 2 つの初歩的な質問があります。Objective C では、オブジェクトを「自動解放」してメソッドから返すときに、オブジェクトを返すメソッドを呼び出す「親メソッド」でそれを「解放」する必要があります。 ?

2 番目の質問は、メソッド (別のオブジェクトのインスタンス メソッド fe userService ) からオブジェクト (fe user ) を返し、それをプロパティ ( self.userProp、オブジェクト userService をインスタンス化し、彼のメソッドを呼び出す) に保存したことです。オブジェクトuserService (メソッドがオブジェクトuserを返し、プロパティself.userPropに格納されている) を解放すると、プロパティに格納されているオブジェクト (プロパティself.userPropに格納されているオブジェクトuser ) も解放されました。なんで?財産内のオブジェクトの所有者は誰でしたか?

ありがとうございました

4

1 に答える 1

2

オブジェクトを「自動解放」してメソッドから返す場合、オブジェクトを再調整するメソッドを呼び出す「親メソッド」でオブジェクトを「解放」する必要がありますか?

いいえ、その理由は次のとおりです。あなたが言った通りに例をレイアウトしましょう:

-(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)。

于 2012-12-10T00:20:21.923 に答える