iOS / MANAGEDOBJECTCONTEXT中的内存管理
-
11-10-2019 - |
题
看来我不了解目标C ...叹气中的内存管理。
我有以下代码(请注意,在我的情况下, placemark.thoroughfare
和 placemark.subThoroughfare
两者都充满了有效的数据,因此 if
- 条件将是 TRUE
item
被绑在一个 ManagedObjectContext
. 。托管变量 item
如 place
有使用的设定器/获取器 @dynamic
. 。因此,声明是
@property (nonatomic, retain) NSString *place;
@dynamic place;
在代码后期,在ReverversGeoCoderDelegate中,我访问它:
- (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
在代码中标记的位置,仪器在那里找到了内存泄漏。如果我这样做,我一旦尝试访问程序就会崩溃 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
许多人并不建议使用释放来简单地重新定位指针。如果要节省一些内存,则不必这样做。
您以前的逻辑确实发布了 两次. 。最初的发行版简单地减少 retainCount
. 。如果是0,则将对象交易。直到对象将其交易 retainCount
是0。
假设你 物品 有属性 保持 从那以后 stringWithFormat:
返回 autoreleased
字符串,所以在第二版本中,您正在尝试释放将要发布的内容 autoreleased
反正。
多次清除对象的最佳方法是简单地分配 nil
对此。
其他提示
一个起点是重新阅读有关属性的阅读,因为您无需在任何地方进行``[item.place release]''。因此您可以删除它们。运行时创建的动态代码使该属性自动处理先前分配给其的任何内容。
另外, [NSString stringWithFormat:...
创建一个自动发行对象(不确定您是否知道:-),这意味着如果您在哪里手动管理变量的内存(不是属性),则必须保留/释放它。但是由于您正在使用属性,因此不使用。
我看不出为什么仪器正在找到内存泄漏。也许更高的代码与之有关。例如,如果你去 item.place = [NSString alloc] initWith...];
那我认为你会需要它。
我怀疑的崩溃是因为发布导致保留计数为零并触发执行不良访问错误。
希望有帮助。