Obj-C,引用计数对象在发布后使​​用?

时间:2012-03-25 21:41:47

标签: iphone objective-c ios cocoa-touch

我收到以下警告。

引用计数对象在发布后使​​用

为此文件启用了ARC。

我还没有将我的应用转换为使用ARC,而且目前还没有正确理解它。但是,我很困惑,为什么这个代码应该有问题(它来自一个库),我的意思是我知道自动释放不应该在这里使用?

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    id uuid = [defaults objectForKey:@"uniqueID"];
    if (uuid)
        uniqueID = (NSString *)uuid;
    else {
        CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
        uniqueID = (__bridge NSString *)cfUuid;
        CFRelease(cfUuid);
        [defaults setObject:uniqueID forKey:@"uniqueID"]; // warning here
    }

EDIT @JohnCalsbeek,@ epatel,@ Ceck 谢谢,我刚刚尝试过,我在CFStringRef cfUuid行发出了一个新的警告,说有可能泄漏。

继承完整档案https://github.com/MugunthKumar/MKStoreKit/blob/master/MKSKProduct.m

4 个答案:

答案 0 :(得分:2)

__bridge演员表不是所有权转让。 uniqueID不会成为拥有的引用,因此在带有警告的行中变为无效。您可以使用__bridge_transfer(将所有权转移到Objective-C参考)并移除CFRelease来电,或将呼叫更改为CFRelease,以便在致电{{1}之后}。

答案 1 :(得分:2)

试试这个,抱歉误解哈哈

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
id uuid = [defaults objectForKey:@"uniqueID"];

if (uuid)
    uniqueID = [NSString stringWithString:(NSString *)uuid];
else {
    CFUUIDRef temp = CFUUIDCreate(NULL);
    CFStringRef cfUuid = CFUUIDCreateString(NULL, temp);
    uniqueID = [NSString stringWithString:(__bridge NSString*) cfUuid];
    CFRelease(cfUuid);
    CFRelease(temp);

    [defaults setObject:uniqueID forKey:@"uniqueID"]; // warning here
}

答案 2 :(得分:1)

我相信这条线可能不符合您的预期

uniqueID = (__bridge NSString *)cfUuid;

这是一个简单的演员,下一行实际上会释放cfUuiduniqueID(实际上是同一个对象)。

所以我将以下行的顺序改为

[defaults setObject:uniqueID forKey:@"uniqueID"]; // warning here
CFRelease(cfUuid);

答案 3 :(得分:1)

您使用CFUUIDCreateString(NULL, CFUUIDCreate(NULL)创建一个字符串。然后你指定uniqueID也引用那个字符串。然后使用CFRelease(cfUuid)释放字符串。然后在下一行使用字符串(uniqueID)。这是无效的,因为你刚刚发布了它。