2015-07-20 101 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