Foundation、Core Foundation框架对象
Core Foundation
对象主要在用C语言编写的Core Foundation
框架中,并使用引用计数对象。Core Foundation框架中的retain/release分别为CFRetain()、CFRelease()
(CF对象不属于ARC内存管理)
CF对象和foundation对象很区别很小,只是生成框架不同,连着可以互相在不同框架中使用。因为两者几乎没有区别可以使用简单的C语言即可互相转换。这种转换不需要额外的CPU资源消耗,因此称之为免费桥
Core Foundation变量没有ARC,因此对其操作均为手动引用计数
id和void *的转换
在ARC无效时,可以简单的进行赋值
id obj = [[NSObject alloc] init];
void *obj1 = obj; //简单的赋值 此时obj1不持有该对象
[obj release];
但是在ARC环境下,需要进行转换
id obj = [[NSObject alloc] init];
void *obj1 = (__bridge void *)(obj);
__bridge
是最简单的转换 只是单纯的赋值,并不负责内存管理,导致其安全性很低,很容易访问悬空指针,因此不推荐这么使用
除了 __bridge
外还有__bridge_retained
和__bridge_transfer
转换
__bridge_retained
:使要赋值的变量也持有所赋值的变量(对象引用计数+1)
//ARC有效时
id obj = [[NSObject alloc] init];
void *p = (__bridge_retained void *)(obj);
//等效于 ARC无效于
id obj = [[NSObject alloc] init];
void *p = obj;
[(id)p retain];
__bridge_transfer
: 与其相反,被转换的变量在所持有的对象在该变量被赋值给转换目标后即释放(对象引用计数-1)
//ARC有效时
id obj1 = (__bridge_transfer id)(p);
//等效于 ARC无效于
id obj = (id)p;
[obj retain];
[(id)p release];
Core Foundation
中提供了Toll-Free-Bridge
函数:
CFTypeRef _Nullable CFBridgingRetain(id _Nullable X) {
return (__bridge_retained CFTypeRef)X;
}
id _Nullable CFBridgingRelease(CFTypeRef CF_CONSUMED _Nullable X) {
return (__bridge_transfer id)X;
}
示例:
CFMutableArrayRef cfObject = NULL;
{
id obj = [[NSMutableArray alloc] init];
cfObject = CFBridgingRetain(obj);
CFShow(cfObject);
printf("retain count %ld\n", (long)CFGetRetainCount(cfObject)); //2
}
printf("出了作用域范围引用计数%ld\n", (long)CFGetRetainCount(cfObject));//1
CFRelease(cfObject);
Foundation
框架产生的OC对象也可以作为Core Foundation
框架对象使用
CFMutableArrayRef cfObject = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
printf("retain count %ld\n", (long)CFGetRetainCount(cfObject)); //1
id obj = CFBridgingRelease(cfObject);
printf("转换后的retain count %ld\n", (long)CFGetRetainCount(cfObject)); // 1
NSLog(@"class = %@", obj);