iOS开发OC语言基础总结

本文于 2495 天之前发表,文中内容可能已经过时。

Foundation对象与CoreFoundation对象的区别

Foundation是Objective-C的库,CoreFoundation是C语言的库,所以Foundation对象属于OC的实例,CoreFoundation对象是C语言的实例。
可通过__bridge, __bridge_transfer, __bridge_retianed进行相互转换。

Foundation对象与CoreFoundation对象更重要的区别是ARC下的内存管理问题。在非ARC下,二者均需要手动管理内存。在ARC下,Foundation对象内存会自动管理,CoreFoundation对象需要手动管理。因此,在ARC下两者进行转换操作时,必须处理好内存管理问题。

以NSString对象和CFStringRef对象相互转换为例。

1.非ARC时,无需特殊处理,二者内存均需手动管理。

2.在ARC下,NSString对象与CFStringRef对象相互转换时,需要使用__bridge, __bridge_transfer, __bridge_retianed三者之一,进行处理内存管理权移交问题。
具体如下:

(1) __bridge, 该关键字的含义是:转换后,不改变对象的内存管理者。即原先需要手动的依旧需要手动管理,需要自动管理的依然需要自动管理。

(2) __bridge_transfer,其语义是:将CFStringRef对象转换为NSString对象,并将CFStringRef对象的内存管理权交给系统自动管理,即由手动改为自动管理。

(3) __bridge_retain,其语义是:将NSString对象转换为CFStringRef对象,并将NSString对象的内存管理权由自动改为手动。与__brdge_transfer刚好相反。

总结:MRC下,它们没有区别,都不改变内存管理权。ARC下看表格 ↓

关键字 功能 内存管理权
__bridge C对象转OC对象互转 不改变内存管理权
__bridge_transfer 只可以C对象转OC对象 转换为ARC自动管理
__bridge_retained 只可以OC对象转C对象 转换为手动内存管理

测试代码:

/* __bridge_transfer只用于C对象转OC对象,并将内存管理权改为自动管理 */
const char *cstr = "this is C string";
char *bytes = malloc(strlen(cstr) + 1);
strcpy(bytes, cstr);//cstr 拷贝到 bytes 数组
CFStringRef cStr1 = CFStringCreateWithCStringNoCopy(NULL, bytes, kCFStringEncodingUTF8, kCFAllocatorNull);
free(bytes);
//cStr1 持有了bytes, 但__bridge_transfer转换为ocStr后,释放cStr1对bytes的持有
NSString *ocStr = (__bridge_transfer NSString*)cStr1;
//效果等同于上行代码
//NSString *ocStr = CFBridgingRelease(string5);


/* __bridge_retained只用于OC对象转C对象,并将内存管理权改为手动管理 */
NSString *str = [NSString stringWithFormat:@"OC String%f",5.0];
CFStringRef *cStr = (__bridge_retained CFStringRef)str;
//与上面效果相同
//CFStringRef *cStr = CFBridgingRetain(str);
//需要手动释放
CFRelease(cStr);
微信打赏

意外收获认可,内心充满感激;打赏之举,更添无限动力。