我正在尝试创建一个协议(AppStore),该协议要求conformer实现符合具有关联类型的协议(订阅者)的项目数组(订阅)。
目标 您可以将AppStore视为NSNotificationCenter。我想添加订阅者(比如addObserver ...)。当发生某些事情时,在订阅者上调用handleNewState(如handleNotification :)并传入实际上设置了一些变量的AppState构造函数。库存AppState没有任何可用的属性。
public protocol AppStore {
//trying to have an array of subscriptions in the protocol
//but a concrete Subscriber type needs to be specified, I thought a generic Subscriber would be more flexible here?
var subscriptions:[Subscription<>]{get set}// Reference to generic type 'Subscription' requires arguments in <...>
associatedtype AppStateType:AppState
var appState:AppStateType { get set }
}
extension AppStore {
//so that AppStore can implement this function
public mutating func subscribe<T:protocol<Subscriber, AnyObject>>(aSubscriber:T){
subscriptions.append(Subscription(sub:aSubscriber))
}
}
public protocol Subscriber {
associatedtype AppStateType
func handleNewState(newState:AppStateType)
}
public struct Subscription <T:protocol<Subscriber, AnyObject>> {
private weak var subscriber:T? = nil
init(sub:T){
self.subscriber = sub
}
}
public protocol AppState { }
我应该如何定义var subscriptions:[Subscription<>]?
或者我应该采用不同的方式
我会像这样使用它
public struct OSXAppState:AppState {
var someStateProp:Int = 0
}
extension NSView : Subscriber {
public func handleNewState(newState:OSXAppState){
if newState == 1 { //do this }
else { //do that }
}
}
public struct OSXAppStore : AppStore {
public typealias GenericSubscriber = NSView//???: something more generic "anything that implements Subscriber"
public var subscriptions: [Subscription<GenericSubscriber>] = []
public var appState: AppState = OSXAppState()
}
答案 0 :(得分:1)
我认为你坚持使用AnyObject
才能使用weak
。这可以通过使协议仅限类来更简单地完成。我改变了协议组成
protocol<Subscriber, AnyObject>
到
protocol Subscriber: class
我还添加了
associatedtype GenericSubscriber: SubscriberType
允许通用
Subscription<T: SubscriberType>
在数组中使用。
public protocol Subscriber: class {
associatedtype AppStateType:AppState
func handleNewState(newState:AppStateType)
}
public struct Subscription<T:Subscriber> {
private weak var subscriber:T?
init(sub:T){
self.subscriber = sub
}
}
public protocol AppState { }
public protocol AppStore {
// Allows Subscription<T:Subscriber> to be used as an array element
associatedtype GenericSubscriber:Subscriber
var subscriptions:[Subscription<GenericSubscriber>]{get set}
var appState:AppState { get set }
}
extension AppStore {
// The concrete type of GenericSubscriber is inferred from this context
public mutating func subscribe(aSubscriber: GenericSubscriber){
subscriptions.append(Subscription<GenericSubscriber>(sub:aSubscriber))
}
}
public struct OSXAppState:AppState {
var someStateProp:Int
}
extension NSView : Subscriber {
public func handleNewState(newState:OSXAppState){
}
}