/*
- ARC有效時三種類型轉(zhuǎn)換:
*/
1、__bridge // 轉(zhuǎn)換
2、__bridge_retained // 轉(zhuǎn)換
3、__bridge_transfer // 轉(zhuǎn)換
// __bridge 轉(zhuǎn)換 //////////////////////
// ARC無效時 對應(yīng)的代碼
id obj = [[NSObject alloc] init];
void *p = obj;
id o = p;
[o release];
// 在 ARC 有效時 通過 __bridge轉(zhuǎn)換 id 和 void * 就能夠相互轉(zhuǎn)換
id obj = [[NSObject alloc] init];
void *p = (__bridge void *)obj;
id o = (__bridge id)p;
void *p = (__bridge void )obj;
id o = (__bridge id)p;
/
- 通過 __bridge 轉(zhuǎn)換, id 和 void * 就能夠相互轉(zhuǎn)換。
- 但是轉(zhuǎn)換為 void * 的 __bridge 轉(zhuǎn)換,其安全性與賦值給 __unsafe_unretained 修飾符相近,
- 甚至會更低。如果管理時不注意賦值對象的所有者,就會因懸垂指針而導(dǎo)至程序崩潰。
*/
// __bridge 轉(zhuǎn)換 //////////////////////
/*
- __bridge_retained 轉(zhuǎn)換可使要轉(zhuǎn)換賦值的變量也持有所賦值的對象.
*/
// __bridge_retained 轉(zhuǎn)換 /////////////
// ARC 有效時的代碼
id obj = [[NSObject alloc] init];
void p = (__bridge_retained void)obj;
// ARC 無效時的代碼
id obj = [[NSObject alloc] init];
void *p = obj;
[(id)p retain];
// __bridge_retained ARC 轉(zhuǎn)換
void *p = 0;
{
id obj = [[NSObject alloc] init];
p = (__bridge_retained void )obj;
}
NSLog(@"class=%@", [(__bridge id)p class]);
/
- 變量作用域結(jié)束時,雖然隨著持有強引用的變顯obj失效,對象隨之釋放,
- 但由于 __bridge_retained 轉(zhuǎn)換使變量p看上去處于持有該對象的狀態(tài),
- 因此該對象不會被廢棄。下面我們比較一下ARC無效時的代碼是怎樣的。
*/
// ARC 無效時的代碼
void p = 0;
{
id obj = [[NSObject alloc] init]; / [obj retainCount] -> 1 /
p = [obj retain]; / [obj retainCount] -> 2 /
[obj release]; / [obj retainCount] -> 1 */
}
/*
- [(id)p retainCount] -> 1
- 即
- [obj retainCount] -> 1
- 對象扔存在
*/
NSLog(@"class=%@", [(__bridge id)p class]);
// __bridge_retained 轉(zhuǎn)換 /////////////
/*
- __bridge_transfer 轉(zhuǎn)換提供與 __bridge_retained 相反的動作,
- 被轉(zhuǎn)換的變量所持有的對象在該變量被賦值給轉(zhuǎn)換目標變量后隨后釋放。
*/
// __bridge_transfer 轉(zhuǎn)換 /////////////
// ARC 有效時的代碼
id obj = (__bridge_transfer id)p;
// ARC 無效時的代碼
id obj = (id)p;
[obj retain];
[(id)p release];
// __bridge_transfer 轉(zhuǎn)換 /////////////
/*
- 不使用id型或?qū)ο笮妥兞恳部梢陨?、持有以及釋放對象?/li>
- 雖然可以這樣做,但在ARC中并不推薦這種方法。
*/
// ARC中并不推薦這種方法 /////////////
// ARC 有效時的代碼
void *p = (__bridge_retained void *)[[NSObject alloc] init];
NSLog(@"class=%@", [(__bridge id)p class]);
(void)(__bridge_transfer id)p;
// ARC 無效時的代碼
id p = [[NSObject alloc] init];
NSLog(@"class=%@", [p class]);
[p release];
// ARC中并不推薦這種方法 /////////////