Obj-C, Reference-counted object is used after it is released?

家住魔仙堡 提交于 2019-12-24 16:18:18

问题


I`m getting the following warning.

Reference-counted object is used after it is released

ARC is enabled for this file.

I have not converted my app to use ARC and don`t have an proper understanding of it at this time. However, at a glance I am puzzled why this code should have a problem (its from a library), I mean I know autorelease should not be used here?

    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, @Chuck Thanks, I've just tried that and I get a new warning on CFStringRef cfUuid line, saying potential leak.

Heres the full file https://github.com/MugunthKumar/MKStoreKit/blob/master/MKSKProduct.m


回答1:


Try this one, srry for the miss understanding haha

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:


A __bridge cast is not a transfer of ownership. uniqueID does not become an owning reference, and so becomes invalid at the line with the warning. You can either use __bridge_transfer (which transfers ownership to the Objective-C reference) and remove your CFRelease call, or change the call to CFRelease to be after the call to -setObject:forKey:.




回答3:


I believe it can be this line that doesn't do what you expect

uniqueID = (__bridge NSString *)cfUuid;

It is a simple cast and the next line will actually release both cfUuid and uniqueID (which actually is the same object).

So I'd change the order of the following lines to

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



回答4:


You create a string with CFUUIDCreateString(NULL, CFUUIDCreate(NULL). Then you assign uniqueID to also refer to that string. Then you release the string with CFRelease(cfUuid). Then you use the string (as uniqueID) on the next line. That's invalid, because you just released it.



来源:https://stackoverflow.com/questions/9864335/obj-c-reference-counted-object-is-used-after-it-is-released

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!