猿问
下载APP

如何在NSManagedObject Swift扩展中创建托管对象子类的实例?

如何在NSManagedObject Swift扩展中创建托管对象子类的实例?

当创建一个扩展助手来NSManagedObject创建一个新的托管对象子类时,swift提供了Self模仿的类型,instancetype这很好,但我似乎无法进行类型转换AnyObject。下面的代码没有编译错误'AnyObject'不能转换为'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)
    }}


HUWWW
浏览 54回答 3
3回答

慕沐林林

(现在更新为Swift 3/4。可以在编辑历史中找到早期Swift版本的解决方案。)您可以使用unsafeDowncast到的返回值转换NSEntityDescription.insertNewObject()到Self&nbsp;(这是该方法实际上是所谓的类型):extension&nbsp;NSManagedObject&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;func&nbsp;create(in&nbsp;context:&nbsp;NSManagedObjectContext)&nbsp;->&nbsp;Self&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;classname&nbsp;=&nbsp;entityName() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;object&nbsp;=&nbsp;NSEntityDescription.insertNewObject(forEntityName:&nbsp;classname,&nbsp;into:&nbsp;context) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;unsafeDowncast(object,&nbsp;to:&nbsp;self) &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Returns&nbsp;the&nbsp;unqualified&nbsp;class&nbsp;name,&nbsp;i.e.&nbsp;the&nbsp;last&nbsp;component.&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Can&nbsp;be&nbsp;overridden&nbsp;in&nbsp;a&nbsp;subclass.&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;func&nbsp;entityName()&nbsp;->&nbsp;String&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;String(describing:&nbsp;self) &nbsp;&nbsp;&nbsp;&nbsp;}}然后let&nbsp;obj&nbsp;=&nbsp;YourEntity.createInContext(context)工作和编译器推断obj正确的类型YourEntity。

手掌心

这是通过实现初始化方法(使用Xcode 7.1测试)来解决问题的不同方法:extension&nbsp;NSManagedObject&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Returns&nbsp;the&nbsp;unqualified&nbsp;class&nbsp;name,&nbsp;i.e.&nbsp;the&nbsp;last&nbsp;component.&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Can&nbsp;be&nbsp;overridden&nbsp;in&nbsp;a&nbsp;subclass.&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;func&nbsp;entityName()&nbsp;->&nbsp;String&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;String(self) &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;convenience&nbsp;init(context:&nbsp;NSManagedObjectContext)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;eName&nbsp;=&nbsp;self.dynamicType.entityName() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;entity&nbsp;=&nbsp;NSEntityDescription.entityForName(eName,&nbsp;inManagedObjectContext:&nbsp;context)! &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.init(entity:&nbsp;entity,&nbsp;insertIntoManagedObjectContext:&nbsp;context) &nbsp;&nbsp;&nbsp;&nbsp;}}Init方法具有隐式返回类型,Self并且不需要强制转换技巧。let&nbsp;obj&nbsp;=&nbsp;YourEntity(context:&nbsp;context)创建该YourEntity类型的对象。Swift 3/4更新:extension&nbsp;NSManagedObject&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Returns&nbsp;the&nbsp;unqualified&nbsp;class&nbsp;name,&nbsp;i.e.&nbsp;the&nbsp;last&nbsp;component.&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Can&nbsp;be&nbsp;overridden&nbsp;in&nbsp;a&nbsp;subclass.&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;func&nbsp;entityName()&nbsp;->&nbsp;String&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;String(describing:&nbsp;self) &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;convenience&nbsp;init(context:&nbsp;NSManagedObjectContext)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;eName&nbsp;=&nbsp;type(of:&nbsp;self).entityName() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;entity&nbsp;=&nbsp;NSEntityDescription.entity(forEntityName:&nbsp;eName,&nbsp;in:&nbsp;context)! &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.init(entity:&nbsp;entity,&nbsp;insertInto:&nbsp;context) &nbsp;&nbsp;&nbsp;&nbsp;}}

慕的地10843

在Swift 2中,有一个使用协议和协议扩展的非常智能的解决方案protocol&nbsp;Fetchable{ &nbsp;&nbsp;typealias&nbsp;FetchableType:&nbsp;NSManagedObject &nbsp;&nbsp;static&nbsp;var&nbsp;entityName&nbsp;:&nbsp;String&nbsp;{&nbsp;get&nbsp;} &nbsp;&nbsp;static&nbsp;func&nbsp;createInContext(context:&nbsp;NSManagedObjectContext)&nbsp;->&nbsp;&nbsp;FetchableType}extension&nbsp;Fetchable&nbsp;where&nbsp;Self&nbsp;:&nbsp;NSManagedObject,&nbsp;FetchableType&nbsp;==&nbsp;Self{ &nbsp;&nbsp;static&nbsp;func&nbsp;createInContext(context:&nbsp;NSManagedObjectContext)&nbsp;->&nbsp;FetchableType &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;NSEntityDescription.insertNewObjectForEntityForName(entityName,&nbsp;inManagedObjectContext:&nbsp;context)&nbsp;as!&nbsp;FetchableType &nbsp;&nbsp;}}在每个NSManagedObject子类中添加协议Fetchable并实现该属性entityName。现在该函数MyEntity.createInContext(…)将返回正确的类型而无需进一步的类型转换。
打开App,查看更多内容
随时随地看视频慕课网APP
我要回答