ARC只会管理OC对象,而Core Foundation(简称CF)中的对象是用C语言实现的,这就意味着,分配给CF对象的内存需要手动释放,否则会造成内存泄漏。
单独使用CF对象时,通常不会忘记手动释放内存。然而,OC对象和CF对象之间是可以相互转换的(通过桥接),这时候就很容易犯错。苹果提供了三种桥接转换的方法:
1、__bridge
__bridge只做类型转换,不会改变对象的所有权(这里说的所有权即谁来管理这个对象的内存)。
1)OC对象转成CF对象,test的所有权还在aNSStr手中,由ARC负责释放。
NSString *aNSStr = [[NSString alloc] initWithFormat:@"test"];
CFStringRef aCFStr = (__bridge CFStringRef)aNSStr;
2)CF对象转成OC对象,test的所有权还在aCFStr手中,所以必须手动释放aCFStr,否则会有内存泄漏。
CFStringRef aCFStr = CFStringCreateWithCString(NULL, "test", kCFStringEncodingUTF8);
NSString *aNSStr = (__bridge NSString *)aCFStr;
CFRelease(aCFStr); // 这里必须释放CF对象
2、__bridge_transfer,等价于CFBridgingRelease()
__bridge_transfer除了类型转换,还会把CF对象的所有权移交到OC对象。
CF对象转成OC对象,test的所有权从aCFStr移交到aNSStr手上,由ARC负责释放。
CFStringRef aCFStr = CFStringCreateWithCString(NULL, "test", kCFStringEncodingUTF8);
1)NSString *aNSStr = (__bridge_transfer NSString *)aCFStr;
2)NSString *aNSStr = (NSString *)CFBridgingRelease(aCFStr);
3、__bridge_retained,等价于CFBridgingRetain()
__bridge_retained除了类型转换,还会把OC对象的所有权抢过来给CF对象。
OC对象转成CF对象,aCFStr把test的所有权从aNSStr手里抢过来,所以必须手动释放aCFStr,否则会有内存泄漏。
NSString *aNSStr = [[NSString alloc] initWithFormat:@"test"];
1)CFStringRef aCFStr = (__bridge_retained CFStringRef) aNSStr;
2)CFStringRef aCFStr = (CFStringRef)CFBridgingRetain(aNSStr);
CFRelease(aCFStr); // 这里必须释放CF对象