ARC 对于Core Foundation对象的内存管理是无效,需要手动添加CFRelease、CFRetain消息
// 创建 CFStringRef 对象
CFStringRef strRef = CFStringCreateWithCString(kCFAllocatorDefault, "hello world", kCFStringEncodingUTF8);
// 创建
CTFontRef fontRef = CTFontCreateWithName((CFStringRef)@"ArialMT", 12, NULL);
// 引用计数加一
CFRetain(strRef);
CFRetain(fontRef);
// 引用计数减一
CFRelease(strRef);
CFRelease(fontRef);
对于CFRelease、CFRetain可以直观认为与Object-C中的retain、release等价。因此对于底层Core Foundation对象,依然需要手动引用计数来管理内存。
Core Foundation对象与Object-C对象的转化
- __bridge: 制作类型转化,不操作对象的引用计数,原来的CF对象不需要时,
需要
动手调用CFRelease方法;
NSString *string = [NSString stringWithFormat:...];
CFStringRef cfString = (__bridge CFStringRef)string;
只是单纯地执行了类型转换,没有进行所有权的转移,也就是说,当string对象被释放的时候,cfString也不能被使用了
- __bridge_retain: 类型转换后,将相关对象的引用计数加1,原来的CF对象不需要时,
需要
动手调用CFRelease方法;
NSString *string = [NSString stringWithFormat:...];
CFStringRef cfString = (__bridge_retained CFStringRef)string;
...
CFRelease(cfString); // 由于Core Foundation的对象不属于ARC的管理范畴,所以需要自己release
使用 __bridge_retained 可以通过转换目标处(cfString)的 retain 处理,来使所有权转移。即使 string 变量被释放,cfString 还是可以使用具体的对象。只是有一点,由于Core Foundation的对象不属于ARC的管理范畴,所以需要自己release。
- __bridge_transfre: 类型转换后,将对象的引用计数交给ARC管理,CF对象不需要时,
不需要
调用CFRelease方法;
CFStringRef cfString = CFStringCreate...();
NSString *string = (__bridge_transfer NSString *)cfString;
// CFRelease(cfString); 因为已经用 __bridge_transfer 转移了对象的所有权,所以不需要调用 release
所有权被转移的同时,被转换变量将失去对象的所有权。当Core Foundation对象类型向Objective-C对象类型转换的时候,会经常用到 __bridge_transfer 关键字