最近看了这样一篇文章http://www.linuxidc.com/Linux/2014-03/97626.htm觉得描述得有点浅,不能简单地说 解不解除ARC的所有权。
所以这里写一下我对这三个方法的理解。
__bridge,不改变对象的持有状态,不retain不release。
<p class="p1"><span class="s1">void</span><span class="s2"> *p = </span><span class="s3">0</span><span class="s2">;</span></p><p class="p1"><span class="s2">{</span></p><p class="p1"><span class="s2"> </span><span class="s1">id</span><span class="s2"> obj = [[</span><span class="s4">NSObject</span><span class="s2"> </span><span class="s5">alloc</span><span class="s2">]</span><span class="s5">init</span><span class="s2">];</span></p><p class="p1"><span class="s2"> </span><span class="s1">void</span><span class="s2"> *p = (</span><span class="s1">__bridge</span><span class="s2"> </span><span class="s1">void</span><span class="s2">*)obj;</span></p><p class="p1"><span class="s2">}</span></p><p class="p2"><span class="s7">//</span><span class="s2">此后访问</span><span class="s7">p</span><span class="s2">出错!(悬垂指针)</span></p>
单纯地转换,这样做容易产生悬垂指针,导致崩溃。
id obj = [[NSObject alloc]init]; void *p = (__bridge_retained void*)obj;
__bridge_retained 使p也持有赋值变量,就是说你在arc环境下也要记得对p进行release。
void *p = (__bridge_retained void *)obj
在no-arc环境下等效于:
id obj = [[NSObject alloc]init]; void *p = obj; [(id)p retain];
来个例子:obj在{}作用域以外已经释放,p因为进行了retained所以并没有被释放,内存泄露。
void *p = 0; { id obj = [[NSObject alloc]init]; p = (__bridge_retained void *)obj; } NSLog(@"%@",[(__bridge id)p class]);//输出NSObject
__bridge_transfer就是相反
id obj = (__bridge_transfer id)p;
赋值以后马上进行release操作,在no-arc环境下等效于:
id obj = (id)p; [obj retain]; [(id)p release];
时间: 2024-10-10 00:07:55