如何从Unmanaged<AnyObject>
类型的对象获取Swift类型的值。我的例子是使用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;
}
我似乎找不到正确的向下转换/转换组合,所以任何帮助都会受到赞赏。
答案 0 :(得分:39)
由于NoOne在我解决之前回答,我会在这里添加答案:
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>!
类型,并且需要向下转换。通用公式似乎是:
var unmanagedObject: Unmanaged<AnyObject> = someFunctionThatReturnsAnUnmanagedObject()
var newValue: Type = unmanagedObject.takeRetainedValue as Type
答案 1 :(得分: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)")
}
}
}
}
}