Using Swift protocols with generics

纵饮孤独 提交于 2019-11-28 08:50:57
Martin R

I cannot explain why your code causes a runtime exception. But it works if you change the function prototype

class func create<T : CoreDataModel>(aClass:T.Type, context:NSManagedObjectContext) -> T 

to

class func create<T : NSManagedObject where T: CoreDataModel>(aClass:T.Type, context:NSManagedObjectContext) -> T

Assuming that your managed object subclass conforms to the protocol, for example

extension Event : CoreDataModel {
    class func entityName() -> String {
        return "Event"
    }
}

then this works and creates a new object:

let newManagedObject = AbstractModel.create(Event.self, context: context)

Alternatively, you could use the approach from the answer to "Swift: return Array of type self" and define an extension to the NSManagedObjectContext class:

extension NSManagedObjectContext {
    func create<T : NSManagedObject where T : CoreDataModel >(entity: T.Type) -> T {
        var classname = entity.entityName()
        var object = NSEntityDescription.insertNewObjectForEntityForName(classname, inManagedObjectContext: self) as T
        return object
    }
}

Then a new object would be created as

let newManagedObject = context.create(Event.self)

From "The Swift Programming Language"

Because T is a placeholder, Swift does not look for an actual type called T.

As T is not a real type, it is maybe not useful to cast to T.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!