2012-03-25 41 views
32

我很困惑bridgebridge_transfer,這是正確的嗎?iOS橋vs bridge_transfer

-(void)getData{ 
    ABAddressBookRef addressBook = ABAddressBookCreate(); 
    NSArray *allPeople = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook); 

    NSString *name; 
    for (int i = 0; i < [allPeople count]; i++) 
    { 
     name = (__bridge_transfer NSString *) ABRecordCopyValue((__bridge ABRecordRef)[allPeople objectAtIndex:i], kABPersonFirstNameProperty); 
    } 
    CFRelease(addressBook); 
    allPeople = nil; 
} 

有沒有人能解釋我如何使用它們?

回答

41

如果您啓用了自動引用計數(ARC),則代碼是正確的。

您的報表中有兩個__bridge_transfer。因此,創建的CFObjects的所有權將被轉移到NSObjects。如果您打開了ARC,它們將自動釋放。如果您使用__bridge代替這兩個語句,則需要明確呼叫CFRelease以釋放由*Copy API創建的CFObjects。

__bridge聲明也是正確的。因爲你在CF API中引用了一個NSObject。您沒有轉讓所有權,所以ARC會將其釋放。

+0

thx,你能解釋一下什麼是「轉讓所有權」? – Rinat 2012-03-25 11:10:16

+8

所有權是內存管理中一個重要的關鍵概念。對象的「所有者」負責釋放其內存。如果它沒有做到這一點,對象將會泄漏。一個對象可以有多個所有者,所以在這種情況下,超出範圍的最後一個所有者負責解除分配。 ARC會自動執行此操作,但僅適用於Objective-C對象。 CoreFoundation對象是香草C對象,所以你需要給編譯器提示如何處理它們。如果您將「所有權」轉讓給ARC,那麼您認爲ARC有責任解除分配該對象。 – borrrden 2012-03-25 11:25:06

+2

抱歉,遲到的迴應。所有權主要是由誰來負責釋放對象。如果您想了解詳細信息,請參閱[所有權政策](https://developer.apple.com/library/mac/#documentation/CoreFOundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html)。 – 2012-03-25 14:59:32

19

這非常非常簡單,當你使用ARC(自動引用計數)時,編譯器會負責計算你的變量指向了多少個對象。當計數到0時,對象會自動分配。對於來自低級結構的東西,比如核心基礎,編譯器不知道該怎麼做。所以,如果你只是想告訴編譯器「忽略這一個,我會在需要時釋放它」,所以你使用BRIDGE。或Bridge傳輸,如果你想說「把它作爲一個對象並在參考變爲0時釋放它」)。

當你這樣做時,你創建一個副本,在正常情況下應該由「CFRelease」 :

ABAddressBookCopyArrayOfAllPeople(addressBook) 

但是加入這個,你是轉移的所有權轉讓給一個Objective-C的對象:

NSArray *allPeople = (__bridge_transfer NSArray*)........ 

所以NSArray的將ARC管理


注意,如JRG提到,這樣做:

CFRelease(addressBook); 

在不影響反正新創建的對象,而是原來你還是要手動釋放:(這很容易告訴因爲這些方法通常有創建複製他們的名字關鍵字)


的東西,不發生在你的代碼中,但你應該小心的是釋放CFRelease的NULL核心基礎對象將導致錯誤。正如保羅在評論中提到的那樣。

+2

不像'[nil release]'很好,'CFRelease(NULL)'會導致錯誤。 – paulmelnikow 2013-01-30 16:12:53

+1

是的,你是對的,http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFTypeRef/Reference/reference.html「如果cf是NULL,這將導致運行時錯誤,你的應用程序將崩潰「。 – Pochi 2013-01-30 16:42:03

+0

-1:'NSArray * allPeople =(__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);'傳輸返回數組的所有權。這與'addressBook'沒有任何關係。相反,'addressBook'必須被釋放,因爲它是使用「create」方法('ABAddressBookCreate')創建的。否則,它會泄漏。 – 2015-12-02 02:14:28

0

一個編輯:我相信一個零對象上調用CFRelease確實會導致應用崩潰

1

路易斯奧斯卡我還在我的ARC的理解,但我相信通訊錄確實需要CFRelease。 ARC不管理地址簿。 NSArray * allPeople由ARC通過__bridge_transfer投影提示進行管理,並將其作爲原始副本創建。沒有CFRelease,addressBook將會泄漏。