iOS / managedobjectcontextのメモリ管理
-
11-10-2019 - |
質問
目的c ...ため息でメモリ管理を理解していなかったようです。
次のコードがあります(私の場合、 placemark.thoroughfare
と placemark.subThoroughfare
どちらも有効なデータで満たされているため、両方です if
- 条件はそうになります TRUE
item
aに結び付けられています ManagedObjectContext
. 。の管理された変数 item
そのような place
で作成されたセッター/ゲッターがあります @dynamic
. 。したがって、宣言はです
@property (nonatomic, retain) NSString *place;
@dynamic place;
コードの後半では、ReverseCoderDelegateで、私はそれにアクセスします。
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {
if (placemark.thoroughfare) {
[item.place release];
item.place = [NSString stringWithFormat:@"%@ ", placemark.thoroughfare];
} else {
[item.place release];
item.place = @"Unknown Place";
}
if (placemark.thoroughfare && placemark.subThoroughfare) {
// *** problem is here ***
[item.place release];
item.place = [NSString stringWithFormat:@"%@ %@", placemark.thoroughfare , placemark.subThoroughfare];
}
リリースしない場合 item.place
コードのマークされた場所で、Instrumentsはそこにメモリリークを見つけます。もしそうなら、プログラムはアクセスしようとすぐにクラッシュします item.place
問題の外側。
何か案は?
解決
まず第一に、私はこのようなロジックを変更します:
NSString *newPlace = nil;
if (placemark.thoroughfare && placemark.subThoroughfare) {
newPlace = [NSString stringWithFormat:@"%@ %@", placemark.thoroughfare , placemark.subThoroughfare];
}
else {
if (placemark.thoroughfare) {
newPlace = [NSString stringWithFormat:@"%@ ", placemark.thoroughfare];
}
else {
newPlace = @"Unknown Place";
}
}
item.place = newPlace; // Either nil of valid string can be assigned to
リリースを使用して、単純に再イニタイ化ポインターを使用することは、多くの人がそれほど推奨していません。メモリを保存するためにこれを行う必要はありません。
以前のロジックはリリースされます 2回. 。リリースが最初に行うのは、単に減少することです retainCount
. 。 0の場合、オブジェクトは扱われます。オブジェクトはそのまで扱われません retainCount
0です。
あなたを仮定します アイテム プロパティがあります 保持 それ以来 stringWithFormat:
戻り値 autoreleased
文字列、だから2回目のリリースで、あなたはどんなものになるかをリリースしようとしていました autoreleased
とりあえず。
オブジェクトを複数回クリアする最良の方法は、単に割り当てることです nil
それに。
他のヒント
出発点は、どこでも「[item.placeリリース]」を行う必要がないため、プロパティについて再読することです。したがって、それらを削除できます。ランタイムによって作成された動的コードは、プロパティが以前に割り当てられたものを自動的にリリースすることを有効にすることを可能にします。
また、 [NSString stringWithFormat:...
AutorEleaseオブジェクトを作成します(それを知っているかどうかはわかりません:-)つまり、変数のメモリを手動で管理する場合(プロパティではなく)、保持/解放する必要があります。しかし、あなたはプロパティを使用しているので、あなたはそうしません。
楽器がメモリリークを見つけている理由がわかりません。おそらく、いくつかのコードはそれに関係しています。たとえば、行った場合 item.place = [NSString alloc] initWith...];
それからあなたはそれが必要だと思います。
リリースがゼロになり、execの悪いアクセスエラーをトリガーするリリースのために私が疑うクラッシュ。
それが役立つことを願っています。