2015-07-20 33 views
0

假设我有一个假想的猫市场。这些猫由许多猫分销商提供,包括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中,我将在每个文件的顶部都有一个绑定宏,但我不确定如何在此处获得相同的结果。

回答

0

让我们开始添加一个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.allObjectsproviders.setRepresentation快速枚举我们实际上使用任何的供应商这CatService类,如果需要。

+0

希望在不久的将来,'NSHashTable'可以用作'NSHashTable ',它可以改善'allProviders' getter。 – nhgrif

+0

嗨@nhgrif,谢谢你的回复。我一直在寻找的问题的主要部分是如何让cat提供者添加自己的addProvider方法。在objective-c中,我会在文件的顶部有一个宏来获取cat服务的共享实例并调用addProvider,但我不确定如何编写在Swift中自动执行的代码。 – AttilaTheFun