iphone - 引用计数的对象在释放后使用

标签 iphone objective-c ios memory-leaks

对项目进行代码分析,并在[默认值setObject:deviceUuid forKey:@“deviceUuid”]行上获取消息“,释放引用引用对象”。

我看了这个话题
Obj-C, Reference-counted object is used after it is released?
但是找不到解决方案。 ARC已禁用。

// 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"];
    }
}

请帮助找到原因。

最佳答案

问题在这里:

    CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
    deviceUuid = (NSString *)cfUuid;
    CFRelease(cfUuid);
    [defaults setObject:deviceUuid forKey:@"deviceUuid"];

让我们看一下这实际上是做什么的:
    CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));

一个CFUUID被创建(并泄漏)。创建CFStringRef并将其分配给cfUuid。 (注意:名称cfUuid表示cfUuid是CFUUIDRef。当然不是;它是CFStringRef。)
    deviceUuid = (NSString *)cfUuid;

相同的CFStringRef被强制类型转换并分配给deviceUuid。这是,而不是,它是NSString或CFStringRef的新实例,它只是相同实例的类型转换。
    CFRelease(cfUuid);

您释放CFStringRef。由于NSString指向相同的对象,因此您也可以释放它。
    [defaults setObject:deviceUuid forKey:@"deviceUuid"];

在这里,您使用以前发布的类型转换对象。

对陈旧指针的最简单修复是这样的:
    CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
    deviceUuid = (NSString *)cfUuid;
    [defaults setObject:deviceUuid forKey:@"deviceUuid"];
    CFRelease(cfUuid);

但是此代码很危险,并且您已经知道原因:deviceUuid也是无效的。但这并不明显,因此您可以稍后再试。另外,它不能修复CFUUID泄漏。

要修复CFStringRef泄漏,可以使用以下方法:
    deviceUuid = (NSString *)CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
    [defaults setObject:deviceUuid forKey:@"deviceUuid"];
    [deviceUuid autorelease]; // or release, if you don't need it in code not
                              // included in your post

但是,这仍然不能解决CFUUID泄漏。
    CFUUIDRef cfuuid = CFUUIDCreate(NULL);
    deviceUuid = (NSString *)CFUUIDCreateString(NULL, cfuuid);
    CFRelease(cfuuid);
    [defaults setObject:deviceUuid forKey:@"deviceUuid"];
    [deviceUuid autorelease]; // or release, if you don't need it in code not
                              // included in your post

关于iphone - 引用计数的对象在释放后使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9966321/

相关文章:

iphone - 在 iOS 中与 Instagram 上的图像共享文本

objective-c - Objective C : How do I read a string from a file containing a list of strings delimited by/n, 然后分别存储字符串的每个字符

ios - 如何解决体系结构 x86_64 类型为 'sourcecode.module-map' 的问题 : no rule to process file/FBSDKCoreKit. 模块映射'

ios - 使用框架将图像共享到社交媒体

iPhone开发和使用单独的模型文件?

iphone - 开始使用适用于 iOS 或 Android 的 VOIP 应用程序?

ios - ViewController 关闭 swift ios

objective-c - 在所有符合协议(protocol)的类上实现一个类别

ios - 其他图钉后面的标注弹出窗口

iphone - 如何设置 UINavigationBar 上后退按钮的文本?