【发布时间】:2017-03-14 06:02:34
【问题描述】:
我是 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;
}
此方法在CFRelease(tagRef); 行上因EXC_BAD_ACCESS 而崩溃。使用Zombies 进行分析告诉我“Objective-C 消息已发送到地址为 0x60800023f640 的已释放 'CFString (immutable)' 对象 (zombie)。”
我的理解是,我拥有tagRef,因为返回该对象的方法中包含“复制”一词。所以,我应该在完成后打电话给CFRelease()。
如果我删除 CFRelease() 行,程序运行良好。但是我担心在这种情况下会导致内存泄漏。
任何帮助将不胜感激!
【问题讨论】:
-
This 会帮助你。
-
好的。在该链接中接受的答案中,rmaddy 说没有必要释放
extension对象,因为它是通过__bridge_transfer投射转移到ARC 的。那么CF对象extension和objc对象ext是堆上的同一个对象吗? -
我刚刚验证了这一点。在我发布的我自己的代码中,
tagRef和tag是堆上的相同对象(它们具有相同的内存地址)。所以调用CFRelease(tagRef)是在释放这个堆对象,然后我通过return tag返回一个指向这个释放对象的指针,这导致了崩溃。通过删除CFRelease()调用修复。 -
是的,因为
tagRef已转移到 ARC,并被释放了两次,删除CFRelease()应该是解决方法。
标签: ios objective-c memory-management memory-leaks