为了扩展我的 NSManagedObject
子类的一些功能,我定义了一系列协议(protocol):
protocol ManagedObjectFindable {
static func find(format:String, arguments: [AnyObject]?, inContext context:NSManagedObjectContext, entityName:String?) -> Self?
}
protocol UniquelyIdentifiable: ManagedObjectFindable {
var identifier: NSNumber? { get }
static func findWithIdentifier(identifier: Int, inContext context:NSManagedObjectContext) -> Self?
}
因此每个在其数据模型实体中具有标识符的 NSManagedObject
都可以符合 UniquelyIdentifiable
。
为此,我正在使用 Swift 2.0 协议(protocol)扩展,其中:
extension UniquelyIdentifiable {
static func findWithIdentifier(identifier: Int, inContext context:NSManagedObjectContext) -> Self? {
return self.find("identifier == %lld", arguments: [NSNumber(longLong: Int64(identifier))], inContext: context, entityName:nil)
}
}
其中 find 定义为:
extension NSManagedObject: ManagedObjectFindable {
/** returns single entity if found, nil otherwise */
class func find(format:String, arguments: [AnyObject]?, inContext context:NSManagedObjectContext, entityName:String? = nil) -> Self? {
let objectEntityName:String
if let name = entityName {
objectEntityName = name
} else {
objectEntityName = String(self)
}
let fetchRequest = NSFetchRequest()
fetchRequest.entity = NSEntityDescription.entityForName(objectEntityName, inManagedObjectContext: context)
fetchRequest.fetchLimit = 1
fetchRequest.predicate = NSPredicate(format: format, argumentArray: arguments)
var persistentEntityº:NSManagedObject?
context.performBlockAndWait {
do {
let fetchResults = try context.executeFetchRequest(fetchRequest)
if (fetchResults.count != 0){
persistentEntityº = fetchResults.first as? NSManagedObject
}
} catch {}
}
if let persistentEntity = persistentEntityº {
return _safeObjectSelfCast(persistentEntity)
} else {
return nil
}
}
}
func _unsafeObjectSelfCast<T>(obj: AnyObject!) -> T { return obj as! T }
func _safeObjectSelfCast<T>(obj: AnyObject) -> T? { return obj as? T }
现在这些方法正确地返回了 Self?并且编译器在编码时间上保持沉默,但是在编译时它给我错误>
现在的问题是,如果不是在协议(protocol)扩展中实现该方法,我只是扩展我的 NSManagedObject
子类,它会很好,但是当你是在数十个 NSManagedObject
子类中完全复制相同的代码。
任何解决方法,或者我真的遗漏了什么?
最佳答案
简答:
将 Self?
扩展到 NSManagedObject?
。
长答案:协议(protocol)要求中的Self
充当将实现该协议(protocol)的类的占位符。所以如果你有
protocol SomeProtocol {
func returnSomething() -> Self
}
这意味着如果你在 Int
上实现它,函数 returnSomething()
应该返回 Int
,如果你在 上实现它>Double
它应该返回 Double
。
因为你在 NSManagedObject
上实现了 UniquelyIdentifiable
并且你的协议(protocol)有 Self?
要求,你应该返回 NSManagedObject?
.
关于 swift 2.0 : Protocol Extension Class Method returning Self,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33802945/