调用从CFBridgingRelease

时间:2018-01-19 04:12:29

标签: objective-c automatic-ref-counting

  1. serial(NSString *)是使用 CFBridgingRelease
  2. 获得的
  3. 具有此代码的文件不使用ARC( -fno-objc-arc 编译器标志)
  4. ARC将负责释放此内存, 尽管有上述标志,还是必须手动释放?在 使用释放的某些情况似乎导致崩溃 (EXC_BAD_ACCESS)和堆栈跟踪显示一些autoreleasepool 相关代码。
  5. NSString *serial = nil;
    io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,
                                                              IOServiceMatching("IOPlatformExpertDevice"));
    if (platformExpert) {
        CFTypeRef serialNumberAsCFString =
        IORegistryEntryCreateCFProperty(platformExpert,
                                        CFSTR(kIOPlatformSerialNumberKey),
                                        kCFAllocatorDefault, 0);
        if (serialNumberAsCFString) {
            serial = CFBridgingRelease(serialNumberAsCFString);
        }
    
        IOObjectRelease(platformExpert);
    }
    [serial release];
    

2 个答案:

答案 0 :(得分:0)

有两件事看起来很奇怪:

  1. 最后[serial release];看起来很奇怪。您已使用CFBridgingRelease()传递了其值。如果您使用ARC,则无法发送release。如果您不使用ARC,则应在此之后将serial设置为nil,但我想您希望稍后使用其值。所以你不应该发布它。
  2. 我不知道IOServiceGetMatchingService()但您不拥有它(请参阅Get Rule)。 因此,你不应该释放它。

    修改:正如@Rob在下面的评论中所述。毕竟,您是服务对象的所有者,您必须将其释放。我们生活的奇怪时期。

答案 1 :(得分:0)

您应该使用静态分析器( shift + 命令 + B 或在Xcode的“产品”菜单上选择“分析”)会告诉你究竟出了什么问题。如果您单击错误消息旁边的图标,它将显示关于如何结束存在问题的逻辑跟踪:

enter image description here

注意,正如Transitioning to ARC Release Notes所说:

  
      
  • __bridge_retainedCFBridgingRetain会将指向Core Foundation指针的Objective-C指针转换为您,并将所有权转移给您。

         

    您有责任调用CFRelease或相关函数放弃对象的所有权。

  •   
  • __bridge_transferCFBridgingRelease将非Objective-C指针移动到Objective-C,并将所有权转移到ARC。

         

    ARC负责放弃对象的所有权。

  •   

所以,你真的不应该使用非{ARC}代码CFBridgingRelease。手动引用计数中的CFBridgingRelease仅适用于转换为ARC模式。“如果你在手动引用计数代码中查看这个函数的定义,它确实会autorelease(模拟清理ARC会为你做的)。但正如文档所述,它只是在将您的代码库转换为ARC时才有用。

但是,正如你所看到的那样,如果你正在做autorelease,而你手动release,那么你就过度释放了。

最重要的是,如果您正在编写手动引用计数代码,并且希望转移所有权以便稍后release,则应使用CFBridgingRetain。如果您将代码段中的CFBridgingRelease替换为CFBridgingRetain并重新分析代码,警告就会消失。

如果您编写了手动引用计数代码,请不要在第一次运行静态分析器时感到沮丧,因为您可能会看到许多问题弹出。但是,一个接一个地插上它们,直到你得到一个健康的清单。