【发布时间】:2016-03-21 11:52:16
【问题描述】:
我有一个AnyObject 数组,我想将它(或一个它的对象)转换为一个泛型类型T,它可能是也可能不是一个数组。
我的第一次尝试:
class MyClass<T> {
func someMethod() -> T? {
let anyObjectArray: [AnyObject] = // ... array obtained from Objective-C framework
if let objectsAsCollection = anyObjectArray as? T { // Cast always fails
return objectsAsCollection
} else if let firstObject = anyObjectArray.first as? T {
return firstObject
} else {
return nil
}
}
}
当T 是Array(例如T.self == Array<SomeObject>.self)时,第一个if let 转换失败。
我会尝试这样的事情,但它涉及以某种方式引入另一个泛型参数,所以写的无效:
extension MyClass where T == Array<U> {
fun someMethod() -> T? {
let anyObjectArray: [AnyObject] = // ... array obtained from Objective-C framework
if let objectsAsCollection = anyObjectArray.flatMap({ $0 as? U }) {
return objectsAsCollection
} else if let firstObject = anyObjectArray.first as? T {
return firstObject
} else {
return nil
}
}
}
想要这样做的原因是我正在使用 Objective-C 框架 (RestKit) 从 REST API 获取结果。我在 Swift 的顶部构建了一个层,它根据发出的请求将这些结果作为特定类型传回,所以我有一个看起来像这样的 Result 类型:
enum Result<T>: {
case Success(T)
case Failure(Error)
}
T 有时是单个对象,有时是对象数组,但 Objective-C 框架总是以数组形式返回结果。
【问题讨论】:
-
如果不限制
AnyObject数组包含多少个不同 类型的对象,这将很困难。例如,假设您的[AnyObject]拥有NSString以及NSNumber实例:如何将它们转换为原生 Swift 类型的数组?请记住,一般来说,使用泛型,比如T,允许不同的类型调用该方法,但是对于每个这样的调用,T固定为一个单一类型。您确定AnyObject数组将始终只包含单个相同类型的对象吗? -
@dfri 从Objective-C 框架返回的
AnyObject数组理论上可以包含任何类型。然而,实际上我知道 REST API 返回一个特定类型的数组,所以对于每个调用T要么是SomeType要么是Array<SomeType>(其中SomeType取决于返回的对象类型服务器)。 -
我想我最近正在和其他人讨论完全相同的问题,我们通过将
[AnyObject]替换为NSArray解决了这个问题。