首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS ARC 環境下 ABMultiValueCopyArrayOfAllValues 內存洩漏警告的修復:__bridge_transfer

     編輯:程式設計綜合問答

警告代碼


NSArray *emailArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(emailProperty);
// 警告:Potential leak of object emailArray

原因分析

  • ABMultiValueCopyArrayOfAllValues 為 **Core Foundation 風格創建函數**(名稱含 Copy),遵循 **Create Rule**:調用者擁有對象,**需手動釋放**(CFRelease)。
  • __bridge 僅轉換指針,**不轉移所有權**,ARC 不會自動插入 release,導致洩漏。

修復:使用 __bridge_transfer


NSArray *emailArray = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(emailProperty);
// __bridge_transfer 告訴編譯器:所有權轉移給 ARC,ARC 會在變量超出作用域時自動 release

所有權轉移關鍵字對照表

關鍵字方向適用場景
__bridge雙向轉換,不轉移所有權臨時傳遞給 CF 函數,雙方不持有
__bridge_retainedOC → CF,保留所有權(調用者需 CFRelease)將 OC 對象長期存入 CF 容器
__bridge_transferCF → OC,轉移所有權給 ARCCF Create/Copy/Retain 函數返回值賦給 OC 變量

常見 CF Create/Copy 函數(需 __bridge_transfer)

  • CFStringCreateWithFormat
  • CGImageCreateWithImageInRect
  • ABAddressBookCreateWithOptions
  • SecCertificateCopyData
  • 所有命名含 Create、Copy、Retain 的 C 函數

完整安全模板


CFErrorRef error = nil;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(nil, &error);
if (addressBook) {
    // __bridge_transfer 接管所有權
    NSArray *allPeople = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
    // 使用 allPeople...
    // 作用域結束時 ARC 自動 CFRelease(addressBook) 與 allPeople
} else {
    NSLog(@"AddressBook create failed: %@", (__bridge_transfer NSError *)error);
}

總結

遇到 Potential leak 警告且來源為 CF Create/Copy 函數,將 __bridge 改為 __bridge_transfer 即可修復。記住:**Create Rule 返回值必須轉移給 ARC 或手動 CFRelease**。

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