2015-11-19 34 views
0

为了延长我的NSManagedObject子类的一些功能,我已经定义了一系列协议:雨燕2.0:协议扩展类方法返回自

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

为了这个目的,我利用雨燕2.0协议扩展,其中:

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) 
    } 
} 

在哪里找到的定义为:

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 } 

现在这些方法返回正确的自我?和编译器的编码时间沉默,但是当编译它给我的错误Method 'findWithIdentifier(_:inContext:)' in non-final class must return 'Self' to conform to protocol 'UniquelyIdentifiable'

现在的事情是,如果不是实施这种方法的协议扩展,我只想致以NSManagedObject子类,它会去罚款,但是当你在几十个子类中完全复制相同的代码时,这会破坏协议扩展的目的。

任何解决方法,或者我真的错过了什么?

+0

你的代码没有错误编译在我的Xcode 7.1.1 –

+0

@MartinR:尝试添加到NSMOSubclass: 扩展SomeManagedObjectSubclass:UniquelyIdentifiable {} 在这种情况下,它不会...... – ambientlight

回答

2

简短的回答: 变化Self?在延伸到NSManagedObject?

长答案:Self协议需求充当将实现该协议的类的占位符。因此,这意味着,如果你实现它Int,功能returnSomething()应该返回Int,如果你实现它Double它应该返回Double如果你有

protocol SomeProtocol { 
    func returnSomething() -> Self 
} 

由于您正在实施UniquelyIdentifiableNSManagedObject和您的协议有Self?要求,您应该返回NSManagedObject?

+0

对我来说,它应该返回可选(NSManagedObject子类)的实例,不可选(NSManagedObject),是的,它会工作,但你想返回可选(NSManagedObjectSubclass) 返回Self的原因?而不是NSManagedObject?是因为你可以有许多不同的NSManagedObject子类, ,如果子类符合这个协议,它将已经实现findWithIdentifier,这是在协议扩展默认实现。 – ambientlight