Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/93.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c iOS/ManagedObjectContext中的内存管理_Objective C_Ios_Memory Leaks_Autorelease_Convenience Methods - Fatal编程技术网

Objective c iOS/ManagedObjectContext中的内存管理

Objective c iOS/ManagedObjectContext中的内存管理,objective-c,ios,memory-leaks,autorelease,convenience-methods,Objective C,Ios,Memory Leaks,Autorelease,Convenience Methods,看来我不了解客观世界中的内存管理。。。唉 我有以下代码(请注意,在我的例子中,placemark.throughtree和placemark.subthroughtree都填充了有效数据,因此if-条件都将TRUE item绑定到一个ManagedObjectContext。item中的托管变量,如place具有使用@dynamic创建的setter/getter。因此,声明是 @property (nonatomic, retain) NSString *place; @dynamic pla

看来我不了解客观世界中的内存管理。。。唉

我有以下代码(请注意,在我的例子中,
placemark.throughtree
placemark.subthroughtree
都填充了有效数据,因此
if
-条件都将
TRUE

item
绑定到一个
ManagedObjectContext
item
中的托管变量,如
place
具有使用
@dynamic
创建的setter/getter。因此,声明是

@property (nonatomic, retain) NSString *place;
@dynamic place;
在代码的后面,在ReverseGeocoderDelegate中,我访问它:

- (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];
}
如果我不释放
项。将
放在代码中标记的位置,Instruments会在那里发现内存泄漏。如果我释放,程序会在我尝试访问
项时立即崩溃。将
放在有问题的方法之外


有什么想法吗?

一个起点是重新阅读属性,因为您不需要在任何地方执行“[item.place release]”。这样您就可以删除它们。运行时为启用该属性而创建的动态代码会自动处理释放以前分配给它的任何内容

另外,
[NSString stringWithFormat:…
会创建一个自动释放对象(不确定您是否知道:-),这意味着如果您手动管理变量(而不是属性)的内存,则必须保留/释放它。但因为您使用的是属性,所以您不需要

我不明白为什么instruments会发现内存泄漏。可能是更高层的一些代码与此有关。例如,如果您使用
item.place=[NSString alloc]initWith…];
,那么我认为您将需要它

我怀疑这次崩溃是因为释放导致retain计数为零,并触发exec bad访问错误


希望对您有所帮助。

重新阅读属性是一个起点,因为您不需要在任何地方执行“[item.place release]”。这样您就可以删除它们。运行时创建的动态代码用于启用该属性,自动处理释放以前分配给它的任何内容

另外,
[NSString stringWithFormat:…
会创建一个自动释放对象(不确定您是否知道:-),这意味着如果您手动管理变量(而不是属性)的内存,则必须保留/释放它。但因为您使用的是属性,所以您不需要

我不明白为什么instruments会发现内存泄漏。可能是更高层的一些代码与此有关。例如,如果您使用
item.place=[NSString alloc]initWith…];
,那么我认为您将需要它

我怀疑这次崩溃是因为释放导致retain计数为零,并触发exec bad访问错误


希望这能有所帮助。

首先,我要改变逻辑如下:

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
许多人并不推荐使用release来简单地重新初始化指针。若要节省一些内存,就不必这样做

您以前的逻辑会释放两次。释放最初所做的只是减少
retainCount
。如果它为0,则对象将被释放。直到其
retainCount
为0,对象才会被释放

假设您的项目具有属性retain,并且由于
stringWithFormat:
返回
自动删除
字符串,因此在第二个版本中,您尝试释放将要发布的
自动删除


多次清除一个对象的最佳方法是简单地将
nil
赋值给它。

首先,我要更改如下逻辑:

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
许多人并不推荐使用release来简单地重新初始化指针。若要节省一些内存,就不必这样做

您以前的逻辑会释放两次。释放最初所做的只是减少
retainCount
。如果它为0,则对象将被释放。直到其
retainCount
为0,对象才会被释放

假设您的项目具有属性retain,并且由于
stringWithFormat:
返回
自动删除
字符串,因此在第二个版本中,您尝试释放将要发布的
自动删除


多次清除对象的最佳方法是简单地将
nil
赋值给它。

粘贴
place
属性的声明以及其setter方法的定义(如果有)会很有用。你是说你用
@synthesis
生成了getter/setter吗?我使用了@dynamic,因为我知道这对于绑定到ManagedObjectContext的属性是正确的,就像在我的例子中一样粘贴
place
属性的声明以及其setter方法的定义(如果有的话)会很有用。你的意思是你用
@synthesis
生成了getter/setter吗?我使用了@dynamic,因为我知道这对于绑定到ManagedObjectContext的属性是正确的,就像我的案例一样。是的,我应该在问题描述中更详细一点。添加了更多信息。很好。但我认为我的注释仍然适用。看起来t您正在“过度管理”。请从删除所有版本开始。托管对象上下文将处理属性的代码,并将正确管理它。'但因为您正在使用属性,所以您不会。'→ 当然,不总是这样。如果它是一个赋值属性(而赋值是一个默认属性),那么他仍然需要管理内存,尽管这不是一个好主意。而且,他可能有一个自定义setter。@bavarieve-true。我忘了提到我假设属性是用retain属性设置的。只检查了我的一个项目,核心数据生成的类在属性上设置了retain所以希望我的评论是正确的