如何在Swift中多重绑定协议实现?
问题描述:
假设我有一个假想的猫市场。这些猫由许多猫分销商提供,包括SPCA,Cats-R-Us和英镑。我想提供一个通用接口,CatProvider可以通过它来显示他们的猫。我还希望允许CatProvider协议的实现者能够注册提供猫,但我的应用程序没有具体知道它们的存在。例如:如何在Swift中多重绑定协议实现?
protocol Cat {
let name: String { get }
let price: Float { get }
}
protocol CatProvider {
func getCats() -> [Cat]
}
class CatService {
func allCats() -> Set<Cat> {
let catProviders: [CatProvider] = // Get all of the cat providers.
return catProviders.reduce(Set<Cat>()) {
cats, provider in
return cats.union(Set(provider.getCats()))
}
}
}
我试图确定允许我CatProvider对多约束自己的CatProvider协议,而不CatService的知识的最佳途径。即我不希望CatService永远实例化一个CatProvider。是否有可能在Swift中做到这一点?在Objective-C中,我将在每个文件的顶部都有一个绑定宏,但我不确定如何在此处获得相同的结果。
答
让我们开始添加一个NSHashTable
以保留对任何注册自己的提供者的弱引用。
class CatService {
private let providers = NSHashTable.weakObjectsHashTable()
// stuff
}
现在,让我们提供一个装置,把(如果你愿意的话,删除)供应商:
class CatService {
private let providers = NSHashTable.weakObjectsHashTable()
func addProvider(provider: CatProvider) {
providers.addObject(provider)
}
// optional:
func removeProvider(provider: CatProvider) {
providers.removeObject(provider)
}
}
我们可以返回所有供应商的阵列,或一组。
为数组:
var allProviders: [CatProvider]? {
return providers.allObjects as? [CatProvider]
}
作为一家集:
var allProviders: Set<CatProvider>? {
return providers.setRepresentation as? Set<CatProvider>
}
当然,我们可以使用providers.allObjects
或providers.setRepresentation
快速枚举我们实际上使用任何的供应商这CatService
类,如果需要。
希望在不久的将来,'NSHashTable'可以用作'NSHashTable',它可以改善'allProviders' getter。 –
nhgrif
嗨@nhgrif,谢谢你的回复。我一直在寻找的问题的主要部分是如何让cat提供者添加自己的addProvider方法。在objective-c中,我会在文件的顶部有一个宏来获取cat服务的共享实例并调用addProvider,但我不确定如何编写在Swift中自动执行的代码。 – AttilaTheFun