__block/__weak/__bridge的用法说明
来源:互联网 发布:android 内存管理源码 编辑:程序博客网 时间:2024/05/23 21:31
在开发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;}
假设这里的strongObj是一个已经声明好了的对象。
LLVM转换成对应的代码
id __attribute__((objc_ownership(none))) obj1 = strongObj;
相应的会调用
id 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变成0或者nil,然后执行objc_storeWeak函数。
那么objc_destoryWeak函数是干什么的呢?
objc_destoryWeak函数的实现
void objc_destroyWeak(id *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中被重新赋值,__weak不可以。
Block内部能够读取外部局部变量的值。但我们需要改变这个变量的值时,我们需要给它附加上__block修饰符。
__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
- __block/__weak/__bridge的用法说明
- __block和__weak的区别
- __block __weak 的使用讲解
- __block和__weak 的区别
- __weak与__block的区别
- __weak和__block的区别
- __Block和__Weak的区别
- __block和__weak的区别
- __block和__weak的区别
- __weak && __block
- __block __weak
- __block 与 __weak的区别理解
- __block 与 __weak的区别理解
- 关于__block和__weak的详解
- __block与__weak的区别理解
- __weak与__block修饰符的区别
- iOS下的__block与__weak
- __block 与 __weak的区别理解
- 面试问题总结
- sap ABAP 显示计时秒表 函数“SAPGUI_PROGRESS_INDICATOR”
- 9. Palindrome Number
- 工厂模式
- oj刷题—Problem B: C语言习题5.25--文件操作2
- __block/__weak/__bridge的用法说明
- 消息队列的两种模式
- C++ 个人整理
- 关于逗号运算符~
- iOS GCD
- 项目会议记录--QR[2017.03.15]
- HTML和CSS的知识点
- CF 527C Glass Carving 思路
- crash分析相关文章