ARC 類型轉(zhuǎn)換:顯示轉(zhuǎn)換 id 和 void *

/*

  • 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中并不推薦這種方法 /////////////

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容