2014-09-04 27 views
2

我試圖用swift獲取具有特定名稱的聯繫人列表。我有以下代碼:Swift等效於(__bridge NSArray *)

let owner = owners[indexPath.row]; 

var addressBook = ABAddressBookCreateWithOptions(nil, nil) 
var addressBookRef: ABAddressBookRef = Unmanaged<NSObject>.fromOpaque(addressBook.toOpaque()).takeUnretainedValue() 

let ownerName: NSString = owner["name"]! as NSString 

let allContacts = ABAddressBookCopyPeopleWithName(addressBookRef, ownerName) 

println("All Contacts: \(allContacts)") 

顯然,allContacts擁有的Swift.Unmanaged值。我期望allContacts是一個NSArray

在本教程中,我遵循allContacts橋接到NSArray通過添加(__bridge NSArray*)ABAddressBookCopyPeopleWithName(addressBookRef, ownerName)

什麼可能導致此問題?

+0

你可能想分享一個鏈接到這個教程,因爲通常你會使用'(__bridge_transfer NSArray *)'(或'CFBridgingRelease()')將所有權轉讓給ARC。讓生活變得更容易。如果你使用了'(__bridge NSArray *)',那麼你必須手動'CFRelease'到'CFArrayRef'。無論如何,'__bridge'相當於'.takeUnretainedValue()','__bridge_transfer'相當於'.takeRetainedValue()'。僅供參考,不再需要'fromOpaque' /'toOpaque'舞蹈。 – Rob 2014-09-05 02:12:49

回答

6
  1. 你做更多的包裝/展開UnmanagedOpaque類型不是必要的。除非你想指定另一個價值是可變的,這似乎不太可能

    var addressBookRef = addressBook.takeUnretainedValue() 
    

    (再說,你應該使用let優化會感謝你:你行:

    var addressBookRef: ABAddressBookRef = Unmanaged<NSObject>.fromOpaque(addressBook.toOpaque()).takeUnretainedValue() 
    

    相當於。 )

  2. 將參數傳遞給AddressBook API時,您不需要轉換爲Foundation類型,但是...我不能讓ABAddressBookCopyPeopleWithName在我的測試中返回非空數組,即使使用ObjC,也是如此這很難唉。

  3. 如果你只是想打印的數組,你(使用ABAddressBookCopyArrayOfAllPeople,而不是因爲上述問題,但返回數組的用法是一樣的),需要什麼比這更:

    let addressBook: ABAddressBook = 
        ABAddressBookCreateWithOptions(nil, nil).takeRetainedValue() 
    let allContacts = 
        ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue() 
    println("All Contacts: \(allContacts)") 
    

    (想必有時得到addressBook,並用它你要麼檢查ABAddressBookGetAuthorizationStatus()或電話ABAddressBookRequestAccessWithCompletion,對吧?)

  4. 如果你想在陣列中的ABRecord值之間的工作,你需要做一些鑄造的。 CoreFoundation類型橋接到Foundation類型,Foundation數組橋接到Swift數組,但它不能自動從CF橋接到Swift。

    for contact in ((allContacts as NSArray) as [ABRecord]) { 
        let name = ABRecordCopyCompositeName(contact).takeRetainedValue() 
        println(name) 
    } 
    

    (我把括號在for聲明顯示操作的層次,但你實際上並不需要它們在你的代碼。)

+3

您必須在這裏使用'takeRetainedValue()',因爲「複製」函數返回+1保留值。 – 2014-09-05 01:24:02

+0

好的。我從我的測試項目中歸咎於錯誤的複製粘貼。 – rickster 2014-09-05 01:29:18

+0

...也適用於ABAddressBookCreateWithOptions()。 – 2014-09-05 05:43:42