如何在NSManagedObject Swift扩展中创建托管对象子类的实例? [英] How can I create instances of managed object subclasses in a NSManagedObject Swift extension?

查看:198
本文介绍了如何在NSManagedObject Swift扩展中创建托管对象子类的实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在创建 NSManagedObject 的扩展帮助以创建新的托管对象子类时,swift提供 Self 类型mimic instancetype 这是伟大的,但我似乎不能类型从 AnyObject 。以下代码不会编译时出错AnyObject不能转换为自我

When creating an extension helper to NSManagedObject to create a new managed object subclass, swift provides the Self type to mimic instancetype which is great, but i can't seem to typecast from AnyObject. The below code does not compile with error 'AnyObject' is not convertible to 'Self'

帮助?

extension NSManagedObject
{
    class func createInContext(context:NSManagedObjectContext) -> Self {
        var classname = className()
        var object: AnyObject = NSEntityDescription.insertNewObjectForEntityForName(classname, inManagedObjectContext: context)
        return object
    }


    class func className() -> String {
        let classString = NSStringFromClass(self)
        //Remove Swift module name
        let range = classString.rangeOfString(".", options: NSStringCompareOptions.CaseInsensitiveSearch, range: Range<String.Index>(start:classString.startIndex, end: classString.endIndex), locale: nil)
        return classString.substringFromIndex(range!.endIndex)
    }

}


推荐答案

诀窍是使用一个泛型助手方法, self
。您的 className()方法也可以稍微简化,更好的名称可以通过 entityName()

The trick is to use a generic helper method which infers the type of self from the context. Your className() method can also be simplified slightly, and a better name might by entityName():

extension NSManagedObject
{
    class func createInContext(context:NSManagedObjectContext) -> Self {
        return createInContextHelper(context)
    }

    private class func createInContextHelper<T>(context:NSManagedObjectContext) -> T {
        let classname = entityName()
        let object = NSEntityDescription.insertNewObjectForEntityForName(classname, inManagedObjectContext: context) as! T
        return object
    }

    class func entityName() -> String {
        let classString = NSStringFromClass(self)
        // The entity is the last component of dot-separated class name:
        let components = split(classString, { $0 == "." })
        return components.last ?? classString
    }
}

然后

let obj = YourEntity.createInContext(context)

工程,编译器将 obj 的类型正确推荐为 YourEntity

works and the compiler infers the type of obj correctly as YourEntity.

更新:使用如何使用泛型类型获取相同类型的对象,这也可以使用全局可重用函数而不是helper方法将返回值转换为适当的类型:

Update: Using the ideas from How to use generic types to get object with same type, this can also be done with a global reusable function instead of the helper method to cast the return value to the appropriate type:

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

extension NSManagedObject
{
    class func createInContext(context:NSManagedObjectContext) -> Self {
        let classname = entityName()
        let object: AnyObject = NSEntityDescription.insertNewObjectForEntityForName(classname, inManagedObjectContext: context)
        return objcast(object)
    }

    class func entityName() -> String {
        let classString = NSStringFromClass(self)
        // The entity is the last component of dot-separated class name:
        let components = split(classString, { $0 == "." })
        return components.last ?? classString
    }
}






更新 Swift 1.2 / Xcode 6.3 Swift 2 / Xcode 7:

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

extension NSManagedObject
{
    class func createInContext(context:NSManagedObjectContext) -> Self {
        let classname = entityName()
        let object: AnyObject = NSEntityDescription.insertNewObjectForEntityForName(classname, inManagedObjectContext: context)
        return objcast(object)
    }

    class func entityName() -> String {
        let classString = NSStringFromClass(self)
        // The entity is the last component of dot-separated class name:
        let components = classString.componentsSeparatedByString(".")
        return components.last ?? classString
    }
}

unsafeBitCast 而不是注释中建议的辅助方法:

Or with unsafeBitCast instead of a helper method, as suggested in the comments:

extension NSManagedObject
{
    class func createInContext(context:NSManagedObjectContext) -> Self {
        let classname = entityName()
        let object: AnyObject = NSEntityDescription.insertNewObjectForEntityForName(classname, inManagedObjectContext: context)
        return unsafeBitCast(object, self)
    }

    class func entityName() -> String {
        let classString = NSStringFromClass(self)
        // The entity is the last component of dot-separated class name:
        let components = classString.componentsSeparatedByString(".")
        return components.last ?? classString
    }
}

这篇关于如何在NSManagedObject Swift扩展中创建托管对象子类的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆