我正在开发一个 Swift 2.0 框架,它向 NSManagedObjectContext
添加了一些扩展方法。这些方法很有用,但不是使用框架所必需的。我希望我的框架的用户能够选择使用这些扩展方法,或许可以通过实现协议(protocol)来实现。但是,当我提供默认实现时,我想确保 self
始终是 NSManagedObjectContext
。我该怎么做?
最佳答案
现在大多数人都知道 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 编译器在这些扩展中识别出 self
是 NSManagedObjectContext
的实例,因此您可以使用所有适当的方法。
现在,您的框架的用户可以自行决定是否要通过简单地在他们的项目中实现接口(interface)来添加您的扩展方法:
extension NSManagedObjectContext: ManagedObjectContextType {}
这允许框架的作者以更简洁的方式提供扩展和默认实现。
关于swift - Swift 2.0 中有什么方法可以使扩展方法可选实现吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31710995/