由 CoreFoundation
创建、管理的对象,生命周通过手动调用 CFRetain/CFRelease
来管理。
Core Foundation
内存管理的三原则:
- 通过
Create/Copy
方法得到的对象我们是有所有权的。 - 通过
Get
得到的,是没有所有权的。如果想要处理,必须使用CFRetain
添加自己为所有者。 - 如果有一个对象的所有权,在使用完成之后必须使用
CFRelease
释放。
__bridge 用以将 CF 对象转换为 OC 对象,或者 OC 对象转换为 CF 对象,但是不会对对象的 Retain Count、所有权产生任何影响。
__bridge 可以理解为:只是为了让编译通过,其他毫无影响。
__bridge_transfer 等价于 CFBridgingRelease()
,将 CF
对象转换为 OC
对象,并将所有权转移给 ARC
。
所有权转移给 ARC
的本质含义是:最终 CF
对象会被 ARC
生成的代码进行 Retain Count -1
操作或者释放,所以不需要手动调用 CFRelease
。
__bridge_retained 等价于 CFBridgingRetain()
,用以将 OC
对象转换为 CF
对象,并且 Retain Count
立即 +1
。和 __bridge_transfer
转移所有权的差别,__bridge_retained
不存在转移所有权,而应当是赋予 CF
所有权
uint8_t bytes[BYTES_LENGTH] = {0x00};
CFDataRef cfData = CFDataCreate(kCFAllocatorDefault, bytes, BYTES_LENGTH);
NSData *nsData = (__bridge NSData *)cfData;
// 需要手动调用 CFRelease(cfData) 来释放 cfData。
uint8_t bytes[BYTES_LENGTH] = {0x00};
NSData *nsData = [NSData dataWithBytes:bytes length:BYTES_LENGTH];
CFDataRef cfData = (__bridge CFDataRef)nsData;
// 不需要手动调用 CFRelease(cfData) 来释放 cfData
uint8_t bytes[BYTES_LENGTH] = {0x00};
CFDataRef cfData = CFDataCreate(kCFAllocatorDefault, bytes, BYTES_LENGTH);
NSData *nsData = (__bridge_transfer NSData *)cfData;
// 不能再调用 CFRelease(cfData)
uint8_t bytes[BYTES_LENGTH] = {0x00};
NSData *nsData = [NSData dataWithBytes:bytes length:BYTES_LENGTH];
CFDataRef cfData = (__bridge_retained CFDataRef)nsData;
// 必须要 CFRelease(cfData)