Swift相当于(__bridge NSArray*)

jam*_*ick 2 objective-c ios ios7 swift

我试图使用swift获取具有特定名称的联系人列表.我有以下代码:

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)")
Run Code Online (Sandbox Code Playgroud)

显然,allContacts有一个值Swift.Unmanaged.我希望allContacts是一个NSArray.

在我正在关注的教程中allContacts,NSArray通过添加(__bridge NSArray*)来桥接ABAddressBookCopyPeopleWithName(addressBookRef, ownerName).

可能导致问题的原因是什么?

ric*_*ter 6

  1. 你做了更多的包装/展开UnmanagedOpaque类型而不是必要的.你的路线:

    var addressBookRef: ABAddressBookRef = Unmanaged<NSObject>.fromOpaque(addressBook.toOpaque()).takeUnretainedValue()
    
    Run Code Online (Sandbox Code Playgroud)

    相当于:

    var addressBookRef = addressBook.takeUnretainedValue()
    
    Run Code Online (Sandbox Code Playgroud)

    (此外,你应该使用let除非你想为该变量分配另一个值,这似乎不太可能.优化器会感谢你.)

  2. 在将参数传递给AddressBook API时,您不需要强制转换为Foundation类型,但是ABAddressBookCopyPeopleWithName在我的测试中,即使使用ObjC,我也无法返回非空数组,因此很难说.

  3. 如果你只是想打印数组,你只需要这个(ABAddressBookCopyArrayOfAllPeople由于上述问题而使用,但返回数组的使用是相同的):

    let addressBook: ABAddressBook = 
        ABAddressBookCreateWithOptions(nil, nil).takeRetainedValue()
    let allContacts =
        ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
    println("All Contacts: \(allContacts)")
    
    Run Code Online (Sandbox Code Playgroud)

    (大概是在获得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)
    }
    
    Run Code Online (Sandbox Code Playgroud)

    (我在该for语句中加上括号来显示操作的层次结构,但实际上在代码中并不需要它们.)

  • 你必须在这里使用`takeRetainedValue()`因为"复制"函数返回+1保留值. (3认同)