Foundation对象与CoreFoundation对象的区别
Foundation对象与CoreFoundation对象的区别
Foundation对象是OC对象,使用OC语言实现;而Core Foundation 对象是 C 对象,使用C语言实现,两者之间可以通过 __ bridge、__ bridge _ transfer、__ bridge _ retained等关键字转换桥接
Foundation对象和 Core Foundation 对象更重要的区别是ARC下的内存管理问题。在非ARC下两者都需要开发者手动管理内存,没有区别,但是在ARC下系统只会自动管理Foundation对象的释放,而不支持Core Foundation对象的管理。因此在ARC下两者进行转换后必须要确定的对象是由开发者手动管理还是ARC系统继续管理,否则可能导致内存泄露。
下面以NSString对象(Foundation对象)和CFStringRef对象(Core Foundation)为例,介绍两者转换和内存管理的移交问题
-
在非ARC 下,NSSting对象和CFStringRef对象可以直接进行转换都是手动管理无须担心内存问题
-
在ARC下,NSString对象和CFStringRef对象转换是,需要使用 __ bridge、__ bridge _ transfer、__ bridge _ retained 来确定对象管理权限转义问题
1 . __ bridge最常用,他的含义是不改变对象的管理权所有者本来由ARC管理的Foundation对象,转换成Core Foundation 对象后依旧由ARC管理;本来有开发者手动管理的Core Foundation 对象转换成Foundation 对象后继续由开发者手动管理代码如下
// ARC下管理的Foundation对象
NSString * s1 = @"hello";
// 转换后依旧由ARC管理释放
CFStringRef cfstring = (__bridge CFStringRef)s1;`
//开发者手动管理的CoreFoundation对象
CFStringRef s2 = CFStringCreateWithCString(NULL, "hello", kCFStringEncodingASCII);
//转换后依旧由开发者手动管理释放
NSString * fstring = (__bridge NSString*)s2;
2 . __ bridge _ transfer用在将Core Foundation 对象转换成 Foundation 对象时,用于进行内存管理权的移交,即本需要由开发者手动管理释放的Core Foundation 对象转换成 Foundation 对象后,交由ARC来管理对象的释放,开发者不用再关心对象的释放问题因为不会发生内存问题 如下
//开发者手动管理的CoreFoundation对象
CFStringRef s2 = CFStringCreateWithCString(NULL, "hello", kCFStringEncodingASCII);
//转换后不需要由开发者手动管理
NSString * fstring = (__bridge_transfer NSString*)s2;
//Write the same way.
// NSString * fstring = (NSString*)CFBridgingRelease(s2);
3 . __ bridge _ retained用在将 Foundation 对象转换成 Core Foundation 对象时,进行ARC内存管理权的剥夺,即本来有ARC管理的Foundation 对象在转换成CoreFoundation对象后,ARC不再继续管理该对象,需要开发者手动进行释放该对象 不然会发生内存泄露 如下
//ARC下管理的Foundation对象
NSString * s1 = @"hello";
//转换后ARC不再继续管理,需要手动释放
CFStringRef cfstring = (__bridge_retained CFStringRef)s1;
//write the same way
// CFStringRef cfstring = (CFStringRef)CFBridgingRetain(s1);