Object-C 指针 和 C 指针的相互转换 与ARC 并验证__bridge关键字的作用

Object-C 指针 和 C 指针的相互转换 与ARC 并验证__bridge关键字的作用,第1张

概述引用计数器 1.引用计数器,是伴随对象的产生而产生的。 当我们执行下面语句的时候,它就产生了一个对象,并且默认该对象的引用计数器为1: id obj = [[NSObject alloc] init]; NSLog(@"obj retainCount=%lx", [obj retainCount]); 输出结果: 2014-07-29 18:32:59.346 Te 引用计数器
1.引用计数器,是伴随对象的产生而产生的。 当我们执行下面语句的时候,它就产生了一个对象,并且默认该对象的引用计数器为1:
        ID obj = [[NSObject alloc] init];
        NSLog(@"obj retainCount=%lx",[obj retainCount]);


 输出结果:    
2014-07-29 18:32:59.346 Test_ARC_brIDge[1127:303] obj retainCount=1
2.当我们在上面的代码加上另外一些代码时,如下(在ARC无效的情况下运行):        ID obj = [[NSObject alloc] init];        voID *p =obj;        [(ID)p retain];          NSLog(@"p retainCount=%lx",[(ID)p retainCount]);        NSLog(@"obj retainCount=%lx",[obj retainCount]);


   输出结果:    
2014-07-29 18:26:49.324 Test_ARC_brIDge[1100:303] p retainCount=22014-07-29 18:26:49.327 Test_ARC_brIDge[1100:303] obj retainCount=2
分析上面代码:
	voID *p =obj;        [(ID)p retain];//retainCount+1
  这两句,相当与将p指针指向了obj对象,然后再将它的引用计数器+1,也就是等于2. 所以, (ID)p  obj他们指向的是同一个对象,固他们的引用计数器值是一样的。      __brIDge、__birdge_retained与__brIDge_transfer       1.当我们在ARC有效的情况下运行下面代码:    
ID obj = [[NSObject alloc] init];        voID *p =obj;
你会发现在,ARC有效的情况下,编译器不允许你隐式的将Object-C 指针转换成C指针,即有如下错误提示:


2.__brIDge 
查阅相关文档,我们可以用 __brIDge  关键字来解决这一问题,修改代码如下:
        ID obj = [[NSObject alloc] init];        voID *p =(__brIDge voID *)obj;        NSLog(@"obj retainCount=%x",_objc_rootRetainCount(obj));
编译通过,输出结果:
2014-07-29 19:07:16.807 Test_ARC_brIDge[1296:303] obj retainCount=1 //即P指针指向的该实体仍然是有效的
注意:在使用ARC的时候,编译器不在允许我们明确调用retainCount函数了,使用会报错滴!(因为, ARC模式就是不需要你关心引用计数
3.__brIDge_retained 修改代码,使用__brIDge_retained关键字代替__brIDge关键字:
        ID obj = [[NSObject alloc] init];        voID *p =(__brIDge_retained voID *)obj;        NSLog(@"obj retainCount=%x",_objc_rootRetainCount(obj));

输出结果:
2014-07-29 19:18:04.187 Test_ARC_brIDge[1315:303] obj retainCount=2

结合2和3两点,我们知道__brIDge 与__brIDge_retained的区别是,对象又有权的不同。即__brIDge关键字,不对对象的引用计数器进行任何处理,而__brIDge_retained 关键字则会让对象的引用计数器+1。同理,我们也可以推断出__brIDge_transfer关键字是否同样对对象的所有权做了某些处理呢?

4.__brIDge_transfer
修改代码,验证__brIDge_transfer关键字的作用:
        ID obj = [[NSObject alloc] init];        voID *p =(__brIDge_retained voID *)obj;        NSLog(@"obj retainCount=%x",_objc_rootRetainCount(obj));       ID objOther= (__brIDge_transfer ID)p;        NSLog(@"objOther retainCount=%x",_objc_rootRetainCount(objOther));

输出结果:
2014-07-29 20:20:55.984 Test_ARC_brIDge[1723:303] obj retainCount=22014-07-29 20:20:55.987 Test_ARC_brIDge[1723:303] objOther retainCount=2

结果很让人意外啊:为什么还是2?
以上代码和结论只提供参考,个人水平有限,不一定准确。在此也是为了做个笔记,方便以后翻阅时能解决该疑惑! ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
参考其他文章引用过来的结论:

对象所有权策略是基于引用计数实现的

对象所有权的策略是通过引用计数——通常叫做retain count实现的。每一个对象有一个retaincount变量。

1.创建对象后,它的retaincount是1

2. retain之后,retain count +1

3.release之后 retain count -1 

4.autorelease之后,在自动释放池最后-1

5.对象的retain count减少到0的时候,对象被销毁。

【重要】

不要显式调用对象的retainCount,结果往往具有误导性,作为开发者可能不了解框架式如何对对象retain的。在调试内存管理中,你应该只关注确保你的代码遵循所有权规则。





个人初步结论:
1. __brIDge_retained 告诉ARC 一旦__brIDge_retained转换完成,ARC就不用在负责释放该对象了,使用者需要手动释放,即使用者拥有该对象的持有权。相当于:
    
ID obj = [[NSObject alloc] init];voID *p = obj;[(ID)p retain];
//即当obj变量被释放(出了大括号作用于)时,p变量仍然持有对象的所有权


    
    
2. __brIDge_transfer 告诉ARC 一旦__brIDge_transfer转换完成,ARC要负责释放该对象!相当于:
    
// p 变量原先持有对象的所有权ID obj = (ID)p;[obj retain];[(ID)p release];
//此后,ARC负责对obj对象所有权的管理
    
    
    
                      



参考文章: http://blog.csdn.net/weiwangchao_/article/details/7744972            Core Foundation 框架 (有详细的说明)
http://book.2cto.com/201305/23871.HTML            _objc_rootRetainCount 函数
http://www.cocoachina.com/applenews/devnews/2013/1126/7418.HTML   iOS内存管理策略和实践 总结

以上是内存溢出为你收集整理的Object-C 指针 和 C 指针的相互转换 与ARC 并验证__bridge关键字的作用全部内容,希望文章能够帮你解决Object-C 指针 和 C 指针的相互转换 与ARC 并验证__bridge关键字的作用所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1052373.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存