首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C 與 Core Foundation 互轉完全指南:ARC 下內存管理三大橋接模式詳解

     編輯:關於C語言

背景

OC 對象(`NSString*` 等)與 CF 對象(`CFStringRef` 等)**內存佈局兼容**,可直接強轉指針。但 **ARC 僅管理 OC 對象**,CF 對象需手動 `CFRetain/CFRelease`。轉換時必須明確**所有權轉移**,否則洩漏或雙重釋放崩潰。

三大橋接修飾符

修飾符宏函數所有權變化適用場景
__bridge—**不轉移**,原所有者保持臨時借用、跨 API 傳參
__bridge_retainedCFBridgingRetain()**OC → CF**,ARC 放棄,調用者負責 CFReleaseOC 對象轉 CF 長期持有
__bridge_transferCFBridgingRelease()**CF → OC**,ARC 接管,調用者無需釋放CF 創建函數返回值轉 OC

場景一:OC → CF(臨時使用,__bridge)

NSString *nsStr = @"hello";
CFStringRef cfStr = (__bridge CFStringRef)nsStr;
// 使用 cfStr 調用 CF API
// nsStr 仍由 ARC 管理,無需 CFRelease

場景二:OC → CF(長期持有,__bridge_retained)

NSString *nsStr = [[NSString alloc] initWithFormat:@"test"];
CFStringRef cfStr = (__bridge_retained CFStringRef)nsStr; // ARC 放棄
// ... 長期持有 cfStr ...
CFRelease(cfStr); // 必須手動釋放,否則洩漏

等價宏:`CFStringRef cfStr = (CFStringRef)CFBridgingRetain(nsStr);`

場景三:CF → OC(ARC 接管,__bridge_transfer)

CFStringRef cfStr = CFStringCreateWithCString(NULL, "test", kCFStringEncodingASCII);
NSString *nsStr = (__bridge_transfer NSString *)cfStr; // ARC 接管
// nsStr 現在由 ARC 管理,無需 CFRelease
// 若此處不轉移,需手動 CFRelease(cfStr)

等價宏:`NSString *nsStr = (NSString *)CFBridgingRelease(cfStr);`

場景四:CF → CF(臨時使用,__bridge)

CFStringRef cfStr = CFStringCreateWithCString(NULL, "test", kCFStringEncodingASCII);
NSString *nsStr = (__bridge NSString *)cfStr; // 不轉移所有權
// 使用 nsStr...
CFRelease(cfStr); // 創建者負責釋放

內存洩漏實戰演示

// 錯誤:OC→CF 用 __bridge 但未 CFRelease
CFStringRef cf = (__bridge CFStringRef)[[NSString alloc] initWithString:@"leak"];
// cf 指向的對象無人釋放 → Leak

// 正確:用 __bridge_retained 或 緊接 CFBridgingRelease
CFStringRef cf2 = (__bridge_retained CFStringRef)[[NSString alloc] initWithString:@"ok"];
CFRelease(cf2); // 平衡

最佳實踐清單

  1. **優先用 `__bridge`** 臨時跨 API 傳參,不改變所有權
  2. **CF 創建函數(Create/Copy/Retain)返回值**轉 OC **必須** `__bridge_transfer` / `CFBridgingRelease()`
  3. **OC 對象長期作為 CF 持有**時用 `__bridge_retained` / `CFBridgingRetain()`,並記住 `CFRelease`
  4. **非 ARC 環境**手動 `retain/release` / `CFRetain/CFRelease`,規則同理
  5. 調試洩漏用 **Instruments → Leaks** 或 **静態分析器**

總結

OC/CF 互轉核心是**所有權轉移契約**。`__bridge`(借用)、`__bridge_retained`(轉出)、`__bridge_transfer`(轉入)三者覆蓋所有場景。牢記:**Create 規則適用於 CF 創建函數,ARC 接管需 `__bridge_transfer`**。規範使用三大橋接,消除跨運行時內存管理隱患。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved