2

CLLocationManagerに慣れて、次のinitメソッドを含むいくつかのサンプルクラス定義を見つけました。

- (id) init {
    self = [super init];

    if (self != nil) {
        self.locationManager = [[[CLLocationManager alloc] init] autorelease];
        self.locationManager.delegate = self;
    }
    return self;
}

- (void)dealloc {
    [self.locationManager release];
    [super dealloc];
}

iVarが自動リリースされる理由がわかりません。これは、initメソッドの最後で割り当てが解除されることを意味しませんか?

また、同じサンプルコードにdeallocメソッドのiVarリリースがあるのを見て困惑しています。

何かご意見は?'

4

3 に答える 3

6

locationManager属性で設定される可能性が高いプロパティですretain

基本的に、次のように書くだけです。

self.locationManager = [[CLLocationManager alloc] init];

左側のself.locationManagerセッターは、割り当てられた への参照を保持しますCLLocationManager。しかし、右側のCLLocationManager参照自体は決して解放されません。このマネージャーの保持カウントがゼロになることはなく、オブジェクトが消えることはありません。これにより、メモリ リークが発生します。

これに対処するには 2 つの方法があります。引用したコードスニペットautoreleaseで見たように割り当てられたオブジェクト — または、割り当てられたオブジェクトを一時変数に割り当て、一時変数をlocationManagerプロパティに保持してから、一時変数を明示的に解放します。

CLLocationManager *_temporaryReference = [[CLLocationManager alloc] init];
self.locationManager = _temporaryReference; // this is retained
[_temporaryReference release];

メモリ管理に関しては、どちらのアプローチも同等です。特に iPhone のようなメモリの少ないデバイスでは、自動解放プールが「空」になるのを待つのが嫌いなため、この 2 番目のアプローチを好む人もいます。これにより、オブジェクトの寿命をより厳密に制御できます。

Apple のObjective-C プログラミング言語のドキュメントでは、この属性について詳しく説明しています。

于 2010-04-30T09:31:38.573 に答える
1

一時変数または自動解放のない代替手段があります。

locationManager = [[CLLocationManager alloc] init];

を使用しself.locationManagerないと、その変数のクラスの setter メソッドが呼び出されないため、保持カウントが 2 に増えません。コンパイラは、これらの割り当てを に変更し[self setLocationManager: locationManager];ます。これは、変数を保持としてプロトタイプ化したことを前提としています。

それがクラス変数である場合(それはそうです)、割り当てを行うことができます。これが適切なコーディング プラクティスであるかどうかは議論の余地がありますが、私の意見では、それがクラスの開始のどこにあるかによって異なります。

于 2010-05-06T17:17:53.663 に答える
0

self.locationManager がそれを保持するプロパティである場合、保持を設定します。alloc を実行すると、保持カウントが +1 に設定されます。これは、関数の終了までに +2 になることを意味します。オートリリースというと+1になります(保持性のため)。プロパティに設定した後に明示的に解放することもできますが、コードが少なくて読みやすいです。

于 2010-04-30T09:34:34.153 に答える