我试图在一个类上创建工厂方法,该类自动转换为它所在的类。
extension NSObject {
// how can I get the return type to be the current NSObject subclass
// instead of NSObject?
class func create() -> NSObject {
return self.init()
}
// example: create(type: NSArray.self)
class func create<T:NSObject>(type:T.Type) -> T {
return T()
}
}
示例2有效,但作为类方法没有优势:
let result = NSArray.create(type: NSArray.self)
但我很乐意能够致电:
let result = NSArray.create()
无需事后施放。有没有办法在Swift中做到这一点?
答案 0 :(得分:4)
您可以使用班级Self
:
extension NSObject {
class func create() -> Self {
return self.init()
}
}
let array = NSArray.create()
但我真的不明白你为什么会这么做,因为你也可以添加一个初始化器。
答案 1 :(得分:0)
接受的答案就是诀窍,谢谢!
但是,对于我没有直接调用init
的情况,我需要这个。相反,我有一个NSObject
类型的对象,需要强制向下转换
正如@Hamish从this other SO answer指出的那样,如果你是另一个深层(一个类方法调用的方法),你可以在类方法上使用泛型推理。
class func create() -> Self {
return createInner()
}
class func createInner<T>() -> T {
// upcasting to NSObject to show that we can downcast
let b = self.init() as NSObject
return b as! T
}
let array = NSArray.create() // gives me an NSArray
我仍然无法弄清楚如何编译fetch
部分,所以我仍在使用外部函数。
import CoreData
// callers use
// try fetch(type: SomeMO.self, moc: moc)
func fetch<T:NSManagedObject>(type:T.Type, moc:NSManagedObjectContext) throws -> [T] {
return try T.fetch(moc: moc) as! [T]
}
extension NSManagedObject {
class func makeOne(moc:NSManagedObjectContext) -> Self {
return makeOneInner(moc: moc)
}
private class func makeOneInner<T>(moc:NSManagedObjectContext) -> T {
let name = "\(self)"
let retVal = NSEntityDescription.insertNewObject(forEntityName: name, into: moc)
return retVal as! T
}
class func fetch(moc:NSManagedObjectContext) throws -> [NSManagedObject] {
let fetchReq:NSFetchRequest<NSManagedObject> = self.fetchRequest() as! NSFetchRequest<NSManagedObject>
let retVal = try moc.fetch(fetchReq) as [NSManagedObject]
return retVal
}
}