我是iOS和objc的新手。我有一个编写的方法,它给了我来自UTI的标签类(mime type, file extension etc)
-
- (NSString *)tagForClass:(CFStringRef)tagClass forUTI:(NSString *)UTI {
CFStringRef UTIRef = (__bridge CFStringRef)(UTI);
CFStringRef tagRef = UTTypeCopyPreferredTagWithClass(UTIRef, tagClass);
NSString *tag = (NSString *)CFBridgingRelease(tagRef);
CFRelease(tagRef);
return tag;
}
此方法在EXC_BAD_ACCESS
行上与CFRelease(tagRef);
崩溃。使用Zombies
进行分析告诉我,“Objective-C
消息已发送到已解除分配的”CFString (immutable)
“对象(zombie
),地址为:0x60800023f640
。”< / p>
我理解这一点的方式是,我拥有tagRef
作为返回该对象的方法,其中包含“copy”一词。所以,我应该在完成后调用CFRelease()
。
如果删除CFRelease()
行,程序运行正常。但在这种情况下,我担心会导致内存泄漏。
非常感谢任何帮助!
答案 0 :(得分:0)
Core Foundation中的约定是,当函数名称包含Copy
或Create
时,它返回一个具有+1保留计数的对象。完成对象后,必须在其上调用释放函数以平衡+1。
当您致电CFBridgingRelease(tagRef)
时,会平衡+1。这就是该函数名称中包含 Release
的原因。所以你不应该在对象上调用CFRelease
。这是正确的代码:
- (NSString *)tagForClass:(CFStringRef)tagClass forUTI:(NSString *)UTI {
CFStringRef UTIRef = (__bridge CFStringRef)(UTI);
CFStringRef tagRef = UTTypeCopyPreferredTagWithClass(UTIRef, tagClass);
// You are now responsible for one release of tagRef.
NSString *tag = (NSString *)CFBridgingRelease(tagRef);
// You have now performed one release of tagRef.
return tag;
}
答案 1 :(得分:-1)
我认为,如果你的CFRelease()
已取消Object
或Object
且引用次数为0
,那么Object
引用次数已经0
1}}。因此,您无法释放可能存在问题的Object
。
尝试使用以下语句打印Object
引用计数,以便您了解。
NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)myObject));
此外,如果您使用ARC
,则无需管理Object
引用计数。它将由ARC
管理。