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);