如何使用泛型类型来获取相同类型的对象

Ole*_*kiy 6 generics swift swift-extensions

我有扩展NSManagedObject,应该帮助我在上下文之间传输对象:

extension NSManagedObject {

    func transferTo(#context: NSManagedObjectContext) -> NSManagedObject? {

        return context.objectWithID(objectID)
    }

}
Run Code Online (Sandbox Code Playgroud)

现在它返回对象,NSManagedObject我应该把它投射到我想要的类,像这样:

let someEntity: MyEntity = // ...create someEntity
let entity: MyEntity = someEntity.transferTo(context: newContext) as? MyEntity
Run Code Online (Sandbox Code Playgroud)

有没有办法Swift避免无用的转换,如果我transferTo(context: ...)从类的对象调用MyEntity使它返回类型MyEntity

Mar*_*n R 2

更新:要获得更好的解决方案,请参阅Rob 的回答


如何在 NSManagedObject Swift 扩展中创建托管对象子类的实例类似?,这可以使用通用辅助方法来完成:

extension NSManagedObject {

    func transferTo(context context: NSManagedObjectContext) -> Self {
        return transferToHelper(context: context)
    }

    private func transferToHelper<T>(context context: NSManagedObjectContext) -> T {
        return context.objectWithID(objectID) as! T
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我已将返回类型更改为Self. objectWithID()返回可选值(与 相比objectRegisteredForID(),因此无需在此处返回可选值。

更新: Jean-Philippe Pellet 建议 定义一个全局可重用函数而不是辅助方法来将返回值转换为适当的类型。

我建议定义两个(重载)版本,以使它可以与可选和非可选对象一起使用(没有不需要的自动包装到可选对象中):

func objcast<T>(obj: AnyObject) -> T {
    return obj as! T
}

func objcast<T>(obj: AnyObject?) -> T? {
    return obj as! T?
}

extension NSManagedObject {

    func transferTo(context context: NSManagedObjectContext) -> Self {
        let result = context.objectWithID(objectID) // NSManagedObject
        return objcast(result) // Self
    }

    func transferUsingRegisteredID(context context: NSManagedObjectContext) -> Self? {
        let result = context.objectRegisteredForID(objectID) // NSManagedObject?
        return objcast(result) // Self?
    }
}
Run Code Online (Sandbox Code Playgroud)

(我已经更新了 Swift 2/Xcode 7 的代码。早期 Swift 版本的代码可以在编辑历史中找到。)