swift 2.0 : Protocol Extension Class Method returning Self

标签 swift swift2 protocol-extension

为了扩展我的 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/

相关文章:

ios - NSProcessInfo().systemUptime 错误

仅由特定类实现的 Swift 协议(protocol)

swift - 如何在指定初始化器中调用协议(protocol)扩展初始化器?

ios - SwiftUI 导航链接和 ScrollView 问题

ios - 当我尝试删除 UITableView 部分时 EXC_BAD_ACCESS

swift2 - 使用 inout 关键字 : is the parameter passed-by-reference or by copy-in copy-out (/call by value result)

协议(protocol)扩展中的 Swift 属性观察器?

ios - 如何使用 Swift 4 的 MagicalRecord 正确获取数据?

ios - 如何改变presentViewController Transition动画

ios - 无法调用“jsonObjectWithData”