2014-09-22 51 views
17

如何從類型爲Unmanaged<AnyObject>的對象獲取Swift類型的值。我的例子是使用ABRecordRef從非託管<AnyObject>獲得快速類型的值。例如:ABRecordRef

我創建了一個聯繫對象來管理,一旦我得到ABRecordRef,但我在從ObjC轉換時遇到了問題。下面是我有:

init(recordRef: ABRecordRef) { 
    if let firstName = ABRecordCopyValue(recordRef, kABPersonFirstNameProperty) { 
     self.firstName = firstName 

    } 
} 

如果是ObjC,我會做:

CFTypeRef firstNameRef = ABRecordCopyValue(recordRef, kABPersonFirstNameProperty); 
if (firstNameRef) { 
    self.firstName = (__bridge NSString *)firstNameRef; 
} 

我似乎無法找到向下轉換/轉換的正確組合,所以任何幫助表示讚賞。

回答

33

因爲沒有人回答之前,我解決了這個問題,我會在這裏補充了答案:

firstName.takeRetainedValue() as? String 

如果你看一下Unmanaged結構類型的報頭,你會發現這一點:

/// Get the value of this unmanaged reference as a managed 
/// reference and consume an unbalanced retain of it. 
/// 
/// This is useful when a function returns an unmanaged reference 
/// and you know that you're responsible for releasing the result. 
func takeRetainedValue() -> T 

因此,因爲CFTypeRef在Swift中轉換爲Unmanaged<AnyObject>

Unmanaged使用泛型來定義一個返回類型,並且聲明它,像這樣:

Unmanaged<T> 

我們的目標是Unmanaged<AnyObject>類型,這意味着takeRetainedValue()將返回T型,或在我們的情況下,類型AnyObject的。由於我的房產firstName的類型爲String?,所以我使用可選的向下轉換。

您可以使用takeRetainedValue方法從您的Unmanaged對象中獲取您的價值。在Foundation API中,我猜測他們將主要是Unmanaged<AnyObject>!類型,並且需要downcast。通用公式似乎是:

var unmanagedObject: Unmanaged<AnyObject> = someFunctionThatReturnsAnUnmanagedObject() 
var newValue: Type = unmanagedObject.takeRetainedValue as Type 
3
import UIKit 
import AddressBook 

class ViewController: UIViewController { 

lazy var addressBook: ABAddressBookRef = { 
    var error: Unmanaged<CFError>? 
    return ABAddressBookCreateWithOptions(nil, &error).takeRetainedValue() as ABAddressBookRef 
}() 

@IBAction func GetPeople(sender: UIButton) { 
    var ab: ABAddressBookRef = addressBook 

    switch ABAddressBookGetAuthorizationStatus(){ 
    case .Authorized: 
     println("Authorized") 
     readFromAddressBook(addressBook) 
    case .Denied: 
     println("Denied") 
    case .Restricted: 
     println("Restricted") 
    case .NotDetermined: 
     println("Not determined") 
     ABAddressBookRequestAccessWithCompletion(addressBook, 
      {[weak self] (granted: Bool, error: CFError!) in 
       if granted { 
        let strongSelf = self! 
        println("Access is granted") 
        strongSelf.readFromAddressBook(strongSelf.addressBook) 
       } 
       else{ 
        println("Access is not granted") 
       } 
     }) 
    default: 
     break 
    } 
} 

func readFromAddressBook(addressBook: ABAddressBookRef){ 
    let allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue() as NSArray 

    for person:ABRecordRef in allPeople{ 
     if let firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty) { 
      if let lastName = ABRecordCopyValue(person, kABPersonLastNameProperty) { 
       let ln:String = (lastName.takeRetainedValue() as? String) ?? "" 
       let fn:String = (firstName.takeRetainedValue() as? String) ?? "" 
       println("\(ln) - \(fn)") 
      } 
     } 
    } 
} 

}

+3

歡迎堆棧溢出!當問題中包含對問題問題解決方案的解釋時,答案是最有用的。你會考慮[編輯你的文章](http://stackoverflow.com/posts/28975435/edit)添加更多的細節? – 2015-03-10 22:56:57

+0

感謝您的回答!它幫助了我! – 2015-12-19 21:46:53

相關問題