都为相同的功能提供接口
CoreFoundation
需要人工管理指针。一些方法:CFRetain
,CFRelease
,但是没有autorelease
。
CocoaFoundation
里ARC
模式下,自动管理内存,MRC
模式下一些方法:retain
,release
,autorelease
。
CocoaFoundation
指针与CoreFoundation
转换,需要处理指向对象的所有权,ARC
提供3个修饰符
1、__bridge
,
i). 从Cocoa
转换到Core
,需要人工CFRetain
,否则,Cocoa
指针释放后, 传出去的指针则无效。
ii). 从Core
转换到Cocoa
,需要人工CFRelease
,否则,Cocoa
指针释放后,对象引用计数仍为1,不会被销毁。
__bridge
:
在MRC
与ARC
模式下都需要对对象持有,retain
持有,否则,cocoa指针释放后,core
对象是野指针
MRC
模式下支持直接转换,也可以加上__bridge,
请看下面两个例子
例子1: NSString *str = [NSString stringWithFormat:@"CFStringRef"];
CFStringRef strRef = (__bridge CFStringRef)str;
NSLog(@"%@",strRef);
例子2:NSString *str = [NSString stringWithFormat:@"CFStringRef"];
CFStringRef strRef = (CFStringRef)str;
NSLog(@"ref is %@",strRef);
以上2例都没有对象的所有权
有所有权的两个操作:A:
CFStringRef strRef = (CFStringRef)str;
strRef = CFRetain(strRef);
CFRelease(strRef);
B: strRef = (CFStringRef)CFBridgingRetain(str);
CFRelease(strRef);
2、__bridge_retained
只有ARC
模式下__bridge_retained
才会生效。同时会转移所有权。也就是说cocoa
指针释放后,core
对象还有效。
例子: NSString *str = [NSString stringWithFormat:@"CFStringRef"];
CFStringRef strRef = (__bridge_retained CFStringRef)str;
NSLog(@"%@",strRef);
CFRelease(strRef);
另外获取所有权的方式:
strRef = (CFStringRef)CFBridgingRetain(str);
CFRelease(strRef);
//这个同时支持ARC与MRC
3、__bridge_transfer
把Core
指针所有权转到cocoa
上,同时自动释放core
指针,不需要人工调用CFRelease();
但是__bridge_tansfer
只在ARC上有效,在``MRC上报错。
例子:A:
CFStringRef strRef2 = CFStringCreateWithCString(kCFAllocatorDefault, "transfer CFStringRef", kCFStringEncodingUTF8);
NSString *str2 = (NSString *)strRef2;
NSLog(@"str2 is %@",str2);
CFRelease(strRef2);
B:
CFStringRef strRef2 = CFStringCreateWithCString(kCFAllocatorDefault, "transfer CFStringRef", kCFStringEncodingUTF8);
NSString *str2 = CFBridgingRelease(strRef2);//他会返回一个cocoa对象
NSLog(@"str2 is %@",str2);
C:
CFStringRef strRef2 = CFStringCreateWithCString(kCFAllocatorDefault, "transfer CFStringRef", kCFStringEncodingUTF8);
NSString *str2 = (__bridge_transfer NSString *)strRef2;//transfer对core对象自动CFRelease了,不需要再显示调用了。
NSLog(@"str2 is %@",str2);
注意点:
以上除了使用CFRelease(strRef);
释放内存,也可以使用CFBridgingRelease(strRef);