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];
答案 0 :(得分:0)
有两件事看起来很奇怪:
[serial release];
看起来很奇怪。您已使用CFBridgingRelease()
传递了其值。如果您使用ARC,则无法发送release
。如果您不使用ARC,则应在此之后将serial
设置为nil
,但我想您希望稍后使用其值。所以你不应该发布它。我不知道IOServiceGetMatchingService()
但您不拥有它(请参阅Get Rule)。 因此,你不应该释放它。
修改:正如@Rob在下面的评论中所述。毕竟,您是服务对象的所有者,您必须将其释放。我们生活的奇怪时期。
答案 1 :(得分:0)
您应该使用静态分析器( shift + 命令 + B 或在Xcode的“产品”菜单上选择“分析”)会告诉你究竟出了什么问题。如果您单击错误消息旁边的图标,它将显示关于如何结束存在问题的逻辑跟踪:
注意,正如Transitioning to ARC Release Notes所说:
__bridge_retained
或CFBridgingRetain
会将指向Core Foundation指针的Objective-C指针转换为您,并将所有权转移给您。您有责任调用
CFRelease
或相关函数放弃对象的所有权。
__bridge_transfer
或CFBridgingRelease
将非Objective-C指针移动到Objective-C,并将所有权转移到ARC。ARC负责放弃对象的所有权。
所以,你真的不应该使用非{ARC}代码CFBridgingRelease
。手动引用计数中的CFBridgingRelease
仅适用于转换为ARC模式。“如果你在手动引用计数代码中查看这个函数的定义,它确实会autorelease
(模拟清理ARC会为你做的)。但正如文档所述,它只是在将您的代码库转换为ARC时才有用。
但是,正如你所看到的那样,如果你正在做autorelease
,而你手动release
,那么你就过度释放了。
最重要的是,如果您正在编写手动引用计数代码,并且希望转移所有权以便稍后release
,则应使用CFBridgingRetain
。如果您将代码段中的CFBridgingRelease
替换为CFBridgingRetain
并重新分析代码,警告就会消失。
如果您编写了手动引用计数代码,请不要在第一次运行静态分析器时感到沮丧,因为您可能会看到许多问题弹出。但是,一个接一个地插上它们,直到你得到一个健康的清单。