在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics、Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环境下编译器不会自动管理CF对象的内存,所以当我们创建了一个CF对象以后就需要我们使用CFRelease将其手动释放,那么CF和OC相互转化的时候该如何管理内存呢?答案就是我们在需要时可以使用__bridge,__bridge_transfer,__bridge_retained,具体介绍和用法如下
1.__bridge:CF和OC对象转化时只涉及对象类型不涉及对象所有权的转化;
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com"];
CFURLRef ref = (CFURLRef)url;
上面的这段代码在ARC环境下系统会给出错误提示和错误修正,修正后如下:
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com"];
CFURLRef ref = (__bridge CFURLRef)url;
系统为我们自动添加了__bridge,因为是OC创建的对象并且在转换时没有涉及对象所有权的转换,所以上面的代码不需要加CFRelease
2.__bridge_transfer:常用在讲CF对象转换成OC对象时,将CF对象的所有权交给OC对象,此时ARC就能自动管理该内存;(作用同CFBridgingRelease())
3.__bridge_retained:(与__bridge_transfer相反)常用在将OC对象转换成CF对象时,将OC对象的所有权交给CF对象来管理;(作用同CFBridgingRetain())
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com"];
CFURLRef ref = (__bridge_retained CFURLRef)url;
CFRelease(ref);
当使用_bridge_retained标识符以后,代表OC要将对象所有权交给CF对象自己来管理,所以我们要在ref使用完成以后用CFRelease将其手动释放.
=========================================
__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
__weak __typeof(&*self)weakSelf =self; 等同于__weak UIViewController *weakSelf =self;
__weak的实现原理
声明一个__weak对象
{
id __weak obj = strongObj;
}
id __weak obj = strongObj;
}
假设这里的strongObj是一个已经声明好了的对象。
LLVM转换成对应的代码
id __attribute__((objc_ownership(none))) obj1 = strongObj;
objc_ownership(none))) obj1 = strongObj;
相应的会调用
id obj ;
objc_initWeak(&obj,strongObj);
objc_destoryWeak(&obj);
;
objc_initWeak(&obj,strongObj);
objc_destoryWeak(&obj);
objc_initWeak的实现其实是这样的
id objc_initWeak(id *object, id value) {
*object = nil;
return objc_storeWeak(object, value);
}
object, id value) {
*object = nil;
return objc_storeWeak(object, value);
}
会把传入的object变成0或者nil,然后执行objc_storeWeak函数。
那么objc_destoryWeak函数是干什么的呢?
objc_destoryWeak函数的实现
void objc_destroyWeak(id *object) {
objc_storeWeak(object, nil);
}
object) {
objc_storeWeak(object, nil);
}
也是会去调用objc storeWeak函数。objc initWeak和objc destroyWeak函数都会去调用objc storeWeak函数,唯一不同的是调用的入参不同,一个是value,一个是nil。
那么重点就都落在objc_storeWeak函数上了。
objc storeWeak函数的用途就很明显了。由于weak表也是用Hash table实现的,所以objc storeWeak函数就把第一个传入参数的变量地址注册到weak表中,然后根据第二个入参来决定是否移除。如果第二个参数为0,那么就把__weak变量从weak表中删除记录,并从引用计数表中删除对应的键值记录。
所以如果__weak引用的原对象如果被释放了,那么对应的__weak对象就会被指为nil。__weak就是通过objc_storeWeak函数这些函数来实现的。
============================================__block
__block对象可以在block中被重新赋值,__weak不可以。,https://blog.csdn.net/u014795020/article/details/51088279
Block内部能够读取外部局部变量的值。但我们需要改变这个变量的值时,我们需要给它附加上__block修饰符。
__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。