/*安全
* ARC有效時三種類型轉換:spa
*/3d
1、__bridge // 轉換指針
2、__bridge_retained// 轉換對象
3、__bridge_transfer// 轉換作用域
// __bridge 轉換 //////////////////////it
// ARC無效時 對應的代碼class
id obj = [[NSObject alloc] init];變量
void *p = obj;引用
id o =p;
[o release];
// 在 ARC 有效時 經過 __bridge轉換 id和 void * 就可以相互轉換
id obj = [[NSObjectalloc] init];
void *p = (__bridgevoid *)obj;
id o = (__bridge id)p;
void *p = (__bridgevoid *)obj;
id o = (__bridge id)p;
/*
* 經過 __bridge 轉換, id 和 void * 就可以相互轉換。
* 可是轉換爲 void * 的 __bridge 轉換,其安全性與賦值給 __unsafe_unretained修飾符相近,
* 甚至會更低。若是管理時不注意賦值對象的全部者,就會因懸垂指針而導至程序崩潰。
*/
// __bridge 轉換 //////////////////////
/*
* __bridge_retained 轉換可以使要轉換賦值的變量也持有所賦值的對象.
*/
// __bridge_retained 轉換 /////////////
// ARC 有效時的代碼
id obj = [[NSObject alloc] init];
void *p = (__bridge_retainedvoid*)obj;
// ARC 無效時的代碼
id obj = [[NSObject alloc] init];
void *p = obj;
[(id)p retain];
// __bridge_retained ARC 轉換
void *p =0;
{
id obj = [[NSObject alloc] init];
p = (__bridge_retainedvoid *)obj;
}
NSLog(@"class=%@", [(__bridgeid)p class]);
/*
* 變量做用域結束時,雖然隨着持有強引用的變顯obj失效,對象隨之釋放,
* 但因爲 __bridge_retained 轉換使變量p看上去處於持有該對象的狀態,
* 所以該對象不會被廢棄。下面咱們比較一下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=%@", [(__bridgeid)p class]);
// __bridge_retained 轉換 /////////////
/*
* __bridge_transfer 轉換提供與 __bridge_retained相反的動做,
* 被轉換的變量所持有的對象在該變量被賦值給轉換目標變量後隨後釋放。
*/
// __bridge_transfer 轉換 /////////////
// ARC 有效時的代碼
id obj = (__bridge_transferid)p;
// ARC 無效時的代碼
id obj = (id)p;
[obj retain];
[(id)p release];
// __bridge_transfer 轉換 /////////////
/*
* 不使用id型或對象型變量也能夠生成、持有以及釋放對象。
* 雖然能夠這樣作,但在ARC中並不推薦這種方法。
*/
// ARC中並不推薦這種方法 /////////////
// ARC 有效時的代碼
void *p = (__bridge_retainedvoid *)[[NSObject alloc] init];
NSLog(@"class=%@", [(__bridgeid)p class]);
(void)(__bridge_transferid)p;
// ARC 無效時的代碼
id p = [[NSObject alloc] init];
NSLog(@"class=%@", [p class]);
[p release];
// ARC中並不推薦這種方法 /////////////