iOS Developer

id类型和void *类型的转换

2016-12-13  本文已影响642人  yzawyx0220

在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对象之间的相互变换中。

上一篇 下一篇

猜你喜欢

热点阅读