在Swift 2.0中是否有任何方法可以使扩展方法可选?

时间:2015-07-29 20:58:28

标签: swift swift2

我在Swift 2.0中开发了一个框架,为NSManagedObjectContext添加了一些扩展方法。这些方法很有用,但对于框架的使用不是必需的。我希望我的框架用户可以选择使用这些扩展方法,也许是通过实现协议。但是,当我提供默认实现时,我希望确保self始终为NSManagedObjectContext。我怎么能这样做?

1 个答案:

答案 0 :(得分:2)

大多数人现在都知道Swift 2.0可以专门针对通用参数进行扩展方法,例如,

extension Array where T: Int {
  // This method only appears when T is an Int
  func seven() -> Int {
    return 7
  }
}

也可以用这种方式约束Self,这就是使“选择加入”扩展方法成为可能的原因。这里的关键是where Self: NSManagedObjectContext在下面的扩展中:

public protocol ManagedObjectContextType {
    func from<E: EntityType>(_: E.Type) -> EntityQuery<E>
    func newEntity<E: NSManagedObject where E: EntityType>(_: E.Type) -> E
    func newEntity<E: NSManagedObject where E: EntityType>() -> E
}

/**
Extend `NSManagedObjectContext` with this interface in your project to
benefit from these methods.
*/
extension ManagedObjectContextType where Self: NSManagedObjectContext {
    /**
    Initiates a query whose result type is `E`.
    */
    public func from<E: EntityType>(_: E.Type) -> EntityQuery<E> {
        return EntityQuery(builder: QueryBuilder()).context(self)
    }

    /**
    Inserts a newly allocated entity of type `E` into this `NSManagedObjectContext`.
    */
    public func newEntity<E: NSManagedObject where E: EntityType>(_: E.Type) -> E {
        return NSEntityDescription.insertNewObjectForEntityForName(E.entityNameInManagedObjectModel(persistentStoreCoordinator!.managedObjectModel), inManagedObjectContext: self) as! E
    }

    /**
    Inserts a newly allocated entity of type `E` into this `NSManagedObjectContext`.
    */
    public func newEntity<E: NSManagedObject where E: EntityType>() -> E {
        return newEntity(E)
    }
}

这就是Swift 2.0编译器在这些扩展中认识到selfNSManagedObjectContext的一个实例,因此您可以使用所有适当的方法。

现在,您的框架用户可以自行决定是否要通过在项目中实现接口来添加扩展方法:

extension NSManagedObjectContext: ManagedObjectContextType {}

这允许框架的作者以更简洁的方式提供扩展和默认实现。