主要涉及以下三种用法:
- __bridge
- __bridge_retained
- __bridge_transfer
__bridge
- (void)test
{
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com"]; // url retained
CFURLRef ref = (__bridge CFURLRef)url; // No CFRetain, No CFRelease
// url released
}
__bridge_retained
将 OC 对象转化为 CF 对象时,将 OC 对象的所有权交给 CF 对象,相当于 CFBridgingRetain()
泄露:
- (void)test2
{
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com"]; // url retained
CFURLRef ref = (__bridge_retained CFURLRef)url; // ref CFRetained
// url released
}
不泄露:
- (void)test2
{
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com"]; // url retained
CFURLRef ref = (__bridge_retained CFURLRef)url; // ref CFRetained
CFRelease(ref); // ref CFReleased;如果这里不 CFRelease,就会有内存泄露
// url released
}
__bridge_transfer
将 CF 对象转化为 OC 对象时,将 CF 对象的所有权交给 OC 对象,相当于 CFBridgingRelease()
泄露:
- (void)test3
{
CFStringRef cfString = CFStringCreateWithFormat(NULL, NULL, CFSTR("Hello, world!")); // cfString alloced
}
不泄露:
- (void)test3
{
CFStringRef cfString = CFStringCreateWithFormat(NULL, NULL, CFSTR("Hello, world!")); // cfString alloced
CFRelease(cfString); // cfString CFReleased
}
不泄露:
- (void)test3
{
CFStringRef cfString = CFStringCreateWithFormat(NULL, NULL, CFSTR("Hello, world!")); // cfString alloced
// CFRelease(cfString); // cfString CFReleased
NSString *osString = (__bridge_transfer NSString *)cfString; // cfString CFReleased, osString retained
// osString released
}
总结
- 每一个 CFRetain 都需要一个 CFRelease 对应;
- 每一个 CFCreate 都需要一个 CFRelease 对应;
- __bridge_retained 等价于 CFRetain;
- __bridge_transfer 等价于 CFRelease;
网友评论