我所理解的内存管理:3、Toll-Free Bridging

30、有时候你可能需要用到一些Core Foundation对象(比如CFArrayRef或者CFMutableDictionaryRef),对于这些对象,编译器是不会自动管理它们的生命周期的,你需要使用CFRetain或CFRelease之类的方法来管理它们的持有情况(ownership)。
如果要进行Core Foundation对象和Objective-C对象的相互转换,就可以使用Toll-Free Bridging。
而由于ARC已不能直接使用retain、release等方法,那么在转换的时候就需要将CF指针的持有情况告知OC指针,同理OC指针在转换成CF指针时也要告知其持有情况。

31、Toll-Free Bridging可以使用修饰符来进行转换,有3种转换方法:
(1)、__bridge
用于两个指针间的直接转换,不考虑持有情况;
(2)、__bridge_retained
用于OC指针转换成CF指针,转换之后CF指针也会持有对象。即是,转换后被赋值的指针也会持有对象。
使用CFBridgingRetain函数也有等同效果;
(3)、__bridge_transfer
用于CF指针(官方文档说的是“非OC指针”)转换成OC指针,转换之后CF指针不再持有对象。即是,转换后赋值指针不再持有对象。
使用CFBridgingRelease函数也有等同效果。

以下用4个例子来演示这3个修饰符:
32、__bridge_retained:
创建一个OC指针,通过__bridge_retained将它转换为CF指针,同时打印出retainCount:



分析一下这段代码执行过程中的持有情况:



可以证明,在使用__bridge_retained修饰符转换后CF指针也会持有对象。

33、__bridge:
如果仅仅使用__bridge做直接转换的话,会有什么问题呢?将32代码中的转换修改为使用__bridge,如下:



可以发现,在这种情况下会导致悬挂指针。所以仅仅使用__bridge做直接转换的话有时候是很危险的。

34、__bridge_transfer:
创建一个CF指针,通过__bridge_transfer将它转换为OC指针,同时打印出retainCount:



分析一下这段代码执行过程中的持有情况:



可以证明,在使用__bridge_transfer修饰符转换后CF指针不再持有对象。

35、__bridge:
同样的,试一试仅仅使用__bridge来做直接转换,看看会发生什么问题。将34代码中的转换修改为使用__bridge,并嵌套在一层花括号内限制变量的作用域,如下:



可以发现,在这种情况下会导致内存泄漏。所以在这种情况下仅仅使用__bridge做直接转换也是很危险的。

36、Toll-Free Bridging除了可以做OC指针和CF指针之间的转换,还可以做其他转换,比如上文29(4)提到的id变量和void*变量的相互转换。
虽然在ARC模式下,不允许id变量和void*变量进行直接转换,但是可以使用Toll-Free Bridging来完成这个转换。

37、在研究这种转换之前,先要了解一下void*类型的变量对它指向的对象的持有情况是否会有影响:
(1)、在MRC模式下,由于void*类型并不是NSObject的子类,所以这种类型的变量无法调用retain、retainCount等方法,也即无法影响引用计数。
所以,在MRC模式下void*类型的变量不会对它指向对象的持有情况造成任何影响;
(2)、在ARC模式下,修饰符只能用来修饰OC指针和块指针类型,而void*类型的变量作为一种无类型的变量,修饰符对这种它是不起作用的。
即是说:当定义变量id obj的时候,其实定义的是id __strong obj,而当定义void *obj的时候,定义就仅仅只是void *obj,它的作用类似于使用了__unsafe_unretained修饰符。
所以,在ARC模式下void*类型的变量也不会对它指向的对象的持有情况造成任何影响。

38、前文29(4)的代码在ARC模式下可以使用__bridge来处理如下:

id obj = [[NSObject alloc] init];
void *p = (__bridge void *)obj;
id o = (__bridge id)p;

但是通过上文已知道,仅仅使用__bridge做转换是很危险的,而且void*类型的变量不会持有它指向的对象,这也是很危险的。比如这段代码,总共有3个指针指向了这个NSObject对象,但是它的retainCount却只有2,这样就很容易造成悬挂指针了。

39、如果前两句代码使用__bridge_retained来处理这种转换,代码如下:

id obj = [[NSObject alloc] init];
void *p = (__bridge_retained void *)obj;

由上文已经知道:使用__bridge_retained转换后,被赋值变量也会持有这个对象。所以这段代码其实是相当于在MRC模式下的这样子转换:

id obj = [[NSObject alloc] init];
void *p = obj;
[(id)p retain]; //强转为id类型后才能调用retain

这样void*类型的p变量就拥有了“持有”对象的效果。

40、如果最后一句代码使用__bridge_transfer来处理这种转换,代码如下:

id o = (__bridge_transfer id)p;

由上文已经知道:使用__bridge_transfer转换后,赋值变量不会再持有这个对象。所以这段代码其实是相当于在MRC模式下的这样子转换:

id o = (id)p;
[o retian];
[(id)p release];

这样将p变量赋值给o变量后,p变量便会有“释放”的效果了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容