在ARC无效时,我们可以进行如下所示的隐式强制转换:
/* ARC无效*/
id obj = [[NSObject alloc] init];
void *p = obj;
但是在ARC有效时这样会引起变异错误。
id型或对象型变量赋值给void *或者逆向赋值都需要特定的转换,如果只想单纯的赋值,可以使用“__bridge”:
/* ARC有效*/
id obj = [[NSObject alloc] init];
void *p = (__bridge void *) obj;
id o = (__bridge id) p;
像这样,id和void *类型就可以相互转换。
但是转换为void *的__bridge转换安全性很低。如果管理时不注意赋值对象的所有者,会产生垂悬指针而使程序崩溃。
还有另外两种转换,__bridge_retained和__bridge_transfer转换。
id obj = [[NSObject alloc] init];
void *p = (__bridge_retained void *) obj;
__bridge_retained转换可使要转换赋值的对象也持有所赋值的对象,在ARC无效时如下所示:
/* ARC无效*/
id obj = [[NSObject alloc] init];
void *p = obj;
[(id)p retain];
__bridge_retained转换变为了retain。变量obj和变量p同时持有对象。
__bridge_transfer转换提供与此相反的动作,被转换的变量所持有的对象在该变量被赋值给转换目标后随之释放。
id obj = (__bridge_transfer id) p;
在ARC无效时:
id obj = id(p);
[obj retain];
[(id)p release];
同__bridge_retained与retain类似,__bridge_transfer与release相似。
这些转换多数使用在Objective-C对象和Core Foundation对象之间的相互变换中。
网友评论