在swift中强制转换泛型数组会导致致命错误

时间:2015-11-05 05:29:02

标签: ios arrays swift generics

我有一个充当BLL的类,包装服务协议。服务协议提供SerializableObjectProtocol个对象的列表。例如,我有User,它实现了SerializedObjectProtocol

以下函数将SerializedObjectProtol数组转换为User

public func Get() -> [T]
{
    let result = self._service.Get()

    return result as! [T]
}

结果,我收到以下错误:

 array element cannot be bridged to Objective-C

我知道代码容易出错,因为如果对象不是T,则不能进行向下转换。因此,我可以验证以下内容:

  • T约束实现SerializedObjectProtol,即

       class DataLayer<T:SerializableObjectProtocol>
    
  • T是类型用户。 result是一个用户数组。即[User]

  • 我可以解决这个问题,但我必须手动转换每个项目。因此,这完全正常:

    var returnArray = [T]()
    
    for item in result
    {
        returnArray.append(item as! T)
    }
    
    return returnArray;
    

我刚刚为一个项目选择了Swift,所以我对它的经验有限。结果,我出去看看我正在尝试的是否可能(将数组[S]转换为[T])。似乎数组可能是[Any]

这是Swift中的有效操作吗?或者以这种方式投射是不可能的。

1 个答案:

答案 0 :(得分:3)

一般情况下,无法直接在Any数组与其包含的类型之间进行投射,因为Any在内存中的表示形式完全不同:sizeof(Any) isn&t; t等于sizeof(User)! 10 Any的数组可能长度为320字节,但10 User只需要80字节,这同样适用于任何协议。结论:您需要投射每一个项目。

也许这样做:

return results.map{ $0 as! User }

或者如果您不确定每个项目是否都是User,则只能返回User这样的内容:

return results.flatMap{ $0 as? User }

如果您仍然遇到问题,请发布一些仍会产生错误的最小代码,如果没有实际代码,您很难理解代码的样子