[CFString retain]:发送到deallocated的消息

时间:2012-09-24 14:48:03

标签: ios xcode memory-management

我使用Xcode启用了僵尸,以查找我的进程是否崩溃到内存泄漏。这是一段代码:

- (NSString *)facVersion
{
    return facVersion;
}


- (void) setFacVersion:(NSString*)_facVersion
{
    if(facVersion != nil) [facVersion release];
    facVersion = [_facVersion retain];
}

现在我打电话

NSLog(@"%@", facVersion);
[self setFacVersion:facVersion];

代码与消息

崩溃
  

[CFString retain]:发送给deallocated的消息

你知道问题是什么吗?

4 个答案:

答案 0 :(得分:4)

这是编写错误的setter的典型问题。当对象本身是属性的后备ivar的最后一个所有者时,将属性分配给自身会导致释放有效地释放对象,然后保留在同一个已释放的对象上。您可以通过两种方式解决此问题。检查要分配的对象与属性的当前值是否相同,或者先保留并仅在之后释放。总而言之,解决方案之一:

- (void) setFacVersion:(NSString*)_facVersion
{
    if (facVersion == _facVersion) return;
    [facVersion release];
    facVersion = [_facVersion retain];
}

解决方案二:

- (void) setFacVersion:(NSString*)_facVersion
{
    [_facVersion retain];
    [facVersion release];
    facVersion = _facVersion;
}

顺便说一句,在释放之前检查对象不是nil是多余的。 Objective-C不是Java。

答案 1 :(得分:1)

它应该是setter中的if (facVersion != _facVersion)。否则,如果再次设置相同的对象,您的setter将释放它(导致对象被释放),之后您不能使用它(保留):

- (void) setFacVersion:(NSString*)_facVersion
{
    if(facVersion != _facVersion) {
        [facVersion release];
        facVersion = [_facVersion retain];
    }
}

另外,你知道Automatic Reference Counting (ARC)吗?

  

自动引用计数(ARC)是一种提供的编译器功能   Objective-C对象的自动内存管理。而不是拥有   考虑保留和释放操作,ARC允许您   专注于有趣的代码,对象图和   应用程序中对象之间的关系。

答案 2 :(得分:0)

如果将同一个对象传递给已经设置的setFacVersion,它将首先释放它,然后尝试保留已释放(和解除分配)的对象。

答案 3 :(得分:0)

您在致电保留之前已将其释放。

除非你在发布和保留之前比较指针,否则你应该使用类似的东西:

- (void) setFacVersion:(NSString*)_facVersion
    [_facVersion retain];
    [facVersion release];
    facVersion = _facVersion;
}

这样,如果指针是相同的,就像你演示的那样,你就不会崩溃。

或者让编译器为你合成setter。

相关问题