7

私の appDelegate.h ファイルでは、次のようにします。

CLLocationManager       *locationManager;

@property (nonatomic, retain) CLLocationManager *locationManager;

その後、.m ファイルで次のように記述します。

...

@synthesize locationManager;
...
if ([CLLocationManager locationServicesEnabled])
{

    [myGizmoClass setLocationManagerDisabled:FALSE];

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

    self.locationManager.delegate = self;

    [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];

    [self.locationManager setDistanceFilter:kCLDistanceFilterNone];


    [self.locationManager startUpdatingLocation];

...

それでも、XCode 4.5 で次のようになっています (添付の画像を参照)。

オブジェクトがリークしました: 割り当てられたオブジェクトは、このコード実行パスで後で参照されません

(オブジェクトがリークしました: 割り当てられたオブジェクトは、このコード実行パスで後で参照されません)

一体何?その行の直後に参照します。

問題が発生していません。PS: クラッシュなどはありません。はっきりさせてください。これそのまま動作しています。私はただエラーが嫌いです。私は何かばかげたことを見逃していると確信しています。誰でも助けることができますか?

「もう @property をする必要はありません」などに関しては何も投稿しないでください。このコードは xcode 3.5-4~ish 用に書き戻されました。 XCode 4.5 で許可されている短縮形と、古いプロジェクトが必要とするもの (およびソース コードにまだ含まれているもの)。そのため、.h ファイルの完全な定義を引き続き使用します。プログラミング スタイルの大きな変更は、アプリの次のメジャー アップデートで行われると考えました。(理解に感謝)

4

4 に答える 4

12

問題

これが非 ARC である場合 (私はそれを想定しています)、これがどのように機能しているかを考えてください。

self.locationManager = [[CLLocationManager alloc] init];
    ^                                        ^
    Retains on setting                       |
                                             Retains when allocating

プロパティを設定しているときにこれが保持されるのはなぜですか?

@property (nonatomic, retain) CLLocationManager *locationManager;
                         ^
                    This is why

プロパティを合成すると、getter と setter が生成されます (ほとんどの場合)。nonatomicandretainキーワードは、合成のヒントを提供しています。nonatomic設定をラップして、@synchronized(self)一度に 1 つのスレッドだけが動作するようにしretain、セッターに入力した値を保持するように指示します。合成しないと、これらは有効にならないことに注意することが重要です(Xcodeの古いバージョンの場合、4.5ではありません)。


あなたの場合、何かを2回保持しています。したがって、どこにもリリースがない場合、メモリがリークします。修正は簡単で、次を使用するだけです。

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

なぜこのように動作するのですか?

そうしないと、メソッドから返された自動解放されたオブジェクトが正しく保持されません!

代替ソリューション

autorelease を追加したくない場合は、代わりに基になるインスタンス変数に代入してください。

locationManager = [[CLLocationManager alloc] init];

すべての場合において...

持っているものを最も適切なタイミングでリリースするようにしてください。これらは自動的にリリースされるわけではありません。保持されたプロパティについては、self.locationManager = nil十分です。代替ソリューションについては、実行する必要があります[locationManager release];

于 2012-11-08T17:54:32.550 に答える
2

@propertyに定義されていretainます。したがって、次の行:

self.locationManager = ...

意味的には次のものと同等です。

[self setLocationManager:...]

右辺にあるものは何でも保持します。ただし、右側に指定したのは所有参照です。そう:

[[CLLocationManager alloc] init] // gives an owning reference

self.locationManager = ...       // retains your owning reference; you've now
                                 // incremented the reference count twice

あなたのロケーションマネージャーがリークされます。

于 2012-11-08T17:54:10.540 に答える
1

@property で、locationManager を保持することを示しているようです。したがって、self.locationManager に何かを割り当てると、保持カウントが 1 になります。ただし、alloc も呼び出すため、保持カウントが 2 に増えます (これによりリークが発生します)。

解決策: alloc ステートメントから self を削除します。

locationManager = [[CLLocationManager alloc] init];

于 2012-11-08T17:57:24.487 に答える
1

このコードで確認してください:

CLLocationManager *location = [[CLLocationManager alloc] init];

self.locationManager = location;

[location release];

または、次のようにする必要があります。

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

[[CLLocationManager alloc] init]1にしますretainCount

self.locationManagertoをretainCount1 ずつインクリメントします。

于 2012-11-08T17:54:45.643 に答える