0

私はObjectiveCについては非常に新しいです。私はメモリリークのための便利なコンストラクタを実験しました。

これが私のコンストラクターです

+(Myobject * ) test{
    return [[self alloc] init];
}

そして私はmain.mのこのコードでそれをテストします

Myobject * __weak g = [Myobject test];
NSLog(@"%@",g);

ログが(null)と表示されることを望みます。これは、コンストラクターのポインターがスコープ外になると終了し、保持する強力なポインターがないため、arcがこのオブジェクトをメモリから削除するためです。ただ弱いポインタだけ。

しかし、ログには、オブジェクトがまだ生きているという何かが書かれています。私の理解では、コンストラクターメソッドにこのオブジェクトを保持する強力なポインターがあります。したがって、それは永遠に存在します。

では、どうすればそのポインタを取り除くことができますか?または私は何かを逃しましたか?

4

2 に答える 2

4

メソッドは自動解放さtestれたオブジェクトを返します。オブジェクトへの強い参照がない場合、現在の自動解放プールの最後に破棄されます。あなたはそれを確認することができます

Myobject * __weak g;
@autoreleasepool {
    g = [Myobject test];
    NSLog(@"%@", g); // object still exists here (Correction: might still exist here, see Nikolaus Ruhe's comment)
}
NSLog(@"%@", g);  // should output "(null)"

ARCの命名規則により、メソッドの名前をに変更した場合の動作は異なりますnewTest。その場合、すぐに解放される保持されたオブジェクトを返します。

正確なセマンティクスは、「3.2.2。保持された戻り値」および「3.2.3。保持されていない戻り値」のセクションの自動参照カウントに記載されています。

訂正: Nikolai Ruheが正しく指摘したように、によって返されるオブジェクトが自動解放プールにあることは保証され[Myobject test]ません。コンパイラーは、最適化中に保持/解放/自動解放呼び出しを削除できます。

于 2012-12-10T08:52:03.743 に答える
-1

はい、ログは正しいです。ご覧のとおり、 g は弱い参照ですが、割り当てられたクラス オブジェクトを指しています。さらに、g はここでも範囲外ではないため、ARC が割り当てを解除することに疑問の余地はありません。

于 2012-12-10T08:48:38.583 に答える