Doing code analysis of the project and get the message “Reference-counted object is used after it is released” on the line [defaults setObject: deviceUuid forKey: @ “deviceUuid”];
I watched this topic
Obj-C, Reference-counted object is used after it is released?
But the solution is not found. ARC disabled.
// Get the users Device Model, Display Name, Unique ID, Token & Version Number
UIDevice *dev = [UIDevice currentDevice];
NSString *deviceUuid;
if ([dev respondsToSelector:@selector(uniqueIdentifier)])
deviceUuid = dev.uniqueIdentifier;
else {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
id uuid = [defaults objectForKey:@"deviceUuid"];
if (uuid)
deviceUuid = (NSString *)uuid;
else {
CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
deviceUuid = (NSString *)cfUuid;
CFRelease(cfUuid);
[defaults setObject:deviceUuid forKey:@"deviceUuid"];
}
}
Please help find the cause.
The problems is here:
Let’s go through what this actually does:
A CFUUID is created (and leaked). A CFStringRef is created and assigned to cfUuid. (Note: The name cfUuid implies that cfUuid is a CFUUIDRef. Of course, it isn’t; it’s a CFStringRef.)
That same CFStringRef is type cast and assigned to deviceUuid. This is not a new instance of NSString or CFStringRef, it’s just a typecast of the same instance.
You release the CFStringRef. Since the NSString points to the same object, you also release it.
And here, you use the typecasted object, which was released before.
THe simplest fix to the stale pointer is this:
But this code is dangerous, and you already know why: deviceUuid is also invalid. But this isn’t obvious, so you can trip on it later. Also, it doesn’t fix the CFUUID leak.
To fix the CFStringRef leak, you could use this:
However, this still doesn’t fix the CFUUID leak.