无法使用Swift中KeyType类型的参数列表调用方法
我正在Swift中使用自定义消息调度程序。我想要一个调度器,它可以:无法使用Swift中KeyType类型的参数列表调用方法,swift,generics,Swift,Generics,我正在Swift中使用自定义消息调度程序。我想要一个调度器,它可以: 将枚举作为事件或任何可散列的内容分派 实现一个协议的每个对象都可以添加为侦听器 代码如下: import Foundation protocol EventDispatcherProtocol: class { typealias T: Hashable func dispatcherDidDispatchEvent(event: T) } class EventListenerWrapper<T
- 将枚举作为事件或任何可散列的内容分派
- 实现一个协议的每个对象都可以添加为侦听器
import Foundation
protocol EventDispatcherProtocol: class {
typealias T: Hashable
func dispatcherDidDispatchEvent(event: T)
}
class EventListenerWrapper<T: EventDispatcherProtocol> {
weak var object: T?
init(_ object: T) {
self.object = object
}
}
class EventDispatcher<KeyType: Hashable, U: EventDispatcherProtocol> {
private var objects = Dictionary<KeyType, [EventListenerWrapper<U>]>()
func add(#listener: U, forEvent event: KeyType) {
let wrapper = EventListenerWrapper(object: listener)
// get all wrappers
if let storedWrappers = objects[event] {
// check if there is such objects already wrapped for this type of event
var found = false
for storedWrapper in storedWrappers {
if let storedObject = storedWrapper.object
where (storedObject as! AnyObject) === (wrapper.object as! AnyObject) {
// Found it!
found = true
break
}
}
if found == false {
// If not found then add the wrapper for this event
var updatedWrappers = storedWrappers
updatedWrappers.append(wrapper)
self.objects[event] = updatedWrappers
}
} else {
self.objects[event] = [wrapper]
}
}
func dispatch(event: KeyType) {
// Enumerate through wrappers
if let storedWrappers = objects[event] {
var idxToRemove = [Int]()
var currentIdx = 0
for storedWrapper in storedWrappers {
// if there is object to dispatch - dispatch message
// otherwise add index of this object to remove wrapper later
if let storedObject = storedWrapper.object {
// storedObject.dispatcherDidDispatchEvent(event) /// <- cannot invoke 'this method' with an argument list of type '(KeyType)'
} else {
idxToRemove.append(currentIdx)
}
currentIdx++
}
// enumerate through reversed array of indexes to remove
// and remove items, update wrappers at the end.
idxToRemove = idxToRemove.reverse()
var updatedWrappers = storedWrappers
for idx in idxToRemove {
updatedWrappers.removeAtIndex(idx)
}
objects[event] = updatedWrappers
}
}
}
// EXAMPLE
enum CustomEvent {
case Start, Stop
}
class CustomListener: EventDispatcherProtocol {
func dispatcherDidDispatchEvent(event: CustomEvent) {
println("CustomListener heard that event! \(event)")
}
}
// Create listeners and wrap them
var listener1 = CustomListener()
var listener2 = CustomListener()
// Create dispatcher
var dispatcher = EventDispatcher<CustomEvent, CustomListener>()
dispatcher.add(listener: listener1, forEvent: CustomEvent.Start)
dispatcher.add(listener: listener2, forEvent: CustomEvent.Stop)
dispatcher.dispatch(CustomEvent.Start)
dispatcher.dispatch(CustomEvent.Stop)
storedObject.dispatcherDidDispatchEvent(event)//我认为最好的解决方案是将类声明更改为:
class EventDispatcher<U: EventDispatcherProtocol> {
typealias KeyType = U.T
类事件调度器{
typealias键类型=U.T
它还将跳过冗余的类型声明,从而简化EventDispatcher的创建:
var dispatcher = EventDispatcher<CustomListener<CustomEvent>>()
var dispatcher=EventDispatcher()
编辑:
由于在编写答案时代码被多次修改,因此我附上了完整的解决方案代码示例:
import Foundation
protocol EventDispatcherProtocol {
typealias T: Hashable
func dispatcherDidDispatchEvent(event: T)
}
class EventListenerWrapper<T: EventDispatcherProtocol> {
var object: T?
init(object: T) {
self.object = object
}
}
class EventDispatcher<U: EventDispatcherProtocol> {
typealias KeyType = U.T
private var objects = Dictionary<KeyType, [EventListenerWrapper<U>]>()
func add(#listener: U, forEvent event: KeyType) {
let wrapper = EventListenerWrapper(object: listener)
// get all wrappers
if let storedWrappers = objects[event] {
// check if there is such objects already wrapped for this type of event
var found = false
for storedWrapper in storedWrappers {
if let storedObject = storedWrapper.object
where (storedObject as! AnyObject) === (wrapper.object as! AnyObject) {
// Found it!
found = true
break
}
}
if found == false {
// If not found then add the wrapper for this event
var updatedWrappers = storedWrappers
updatedWrappers.append(wrapper)
self.objects[event] = updatedWrappers
}
} else {
self.objects[event] = [wrapper]
}
}
func dispatch(event: KeyType) {
// Enumerate through wrappers
if let storedWrappers = objects[event] {
var idxToRemove = [Int]()
var currentIdx = 0
for storedWrapper in storedWrappers {
// if there is object to dispatch - dispatch message
// otherwise add index of this object to remove wrapper later
if let storedObject = storedWrapper.object {
storedObject.dispatcherDidDispatchEvent(event) /// <- cannot invoke 'this method' with an argument list of type '(KeyType)'
} else {
idxToRemove.append(currentIdx)
}
currentIdx++
}
// enumerate through reversed array of indexes to remove
// and remove items, update wrappers at the end.
idxToRemove = idxToRemove.reverse()
var updatedWrappers = storedWrappers
for idx in idxToRemove {
updatedWrappers.removeAtIndex(idx)
}
objects[event] = updatedWrappers
}
}
}
// EXAMPLE
enum CustomEvent {
case Start, Stop
}
class CustomListener<T: Hashable>: EventDispatcherProtocol {
func dispatcherDidDispatchEvent(event: T) {
println("CustomListener heard that event! \(event)")
}
}
// Create listeners and wrap them
var listener1 = CustomListener<CustomEvent>()
var listener2 = CustomListener<CustomEvent>()
// Create dispatcher
var dispatcher = EventDispatcher<CustomListener<CustomEvent>>()
dispatcher.add(listener: listener1, forEvent: CustomEvent.Start)
dispatcher.add(listener: listener2, forEvent: CustomEvent.Stop)
dispatcher.dispatch(CustomEvent.Start)
dispatcher.dispatch(CustomEvent.Stop)
<代码>导入基础
协议事件调度协议{
别名T:Hashable
func dispatcherDidDispatchEvent(事件:T)
}
类EventListenerWrapper{
var对象:T?
init(对象:T){
self.object=对象
}
}
类事件调度器{
typealias键类型=U.T
私有变量对象=字典()
func add(#监听器:U,forEvent事件:KeyType){
let wrapper=EventListenerWrapper(对象:侦听器)
//把所有的包装纸都拿来
如果让StoredRappers=对象[事件]{
//检查是否已经为此类事件包装了此类对象
发现的var=false
对于StoredRapper中的StoredRapper{
如果让storedObject=storedWrapper.object
其中(storedObject as!AnyObject)==(wrapper.object as!AnyObject){
//找到了!
找到=真
打破
}
}
如果找到==false{
//如果未找到,则添加此事件的包装
var updatedWrappers=storedWrappers
updatedWrappers.append(包装器)
self.objects[event]=updatedWrappers
}
}否则{
self.objects[event]=[wrapper]
}
}
func分派(事件:KeyType){
//通过包装纸列举
如果让StoredRappers=对象[事件]{
变量idxToRemove=[Int]()
var currentIdx=0
对于StoredRapper中的StoredRapper{
//如果有要分派的对象-分派消息
//否则,请添加此对象的索引,以便稍后删除包装器
如果让storedObject=storedWrapper.object{
storedObject.dispatcherDidDispatchEvent(event)///Rob Napier,CustomEvent enum在默认情况下不是可哈希的吗?可哈希与“EventDispatcher
专用的哈希类型”不同。谢谢。我开始在U.t周围胡闹,几乎在您回答之前就这样做了。无论如何,谢谢您将我直接转到这里;)
var dispatcher = EventDispatcher<CustomListener<CustomEvent>>()
import Foundation
protocol EventDispatcherProtocol {
typealias T: Hashable
func dispatcherDidDispatchEvent(event: T)
}
class EventListenerWrapper<T: EventDispatcherProtocol> {
var object: T?
init(object: T) {
self.object = object
}
}
class EventDispatcher<U: EventDispatcherProtocol> {
typealias KeyType = U.T
private var objects = Dictionary<KeyType, [EventListenerWrapper<U>]>()
func add(#listener: U, forEvent event: KeyType) {
let wrapper = EventListenerWrapper(object: listener)
// get all wrappers
if let storedWrappers = objects[event] {
// check if there is such objects already wrapped for this type of event
var found = false
for storedWrapper in storedWrappers {
if let storedObject = storedWrapper.object
where (storedObject as! AnyObject) === (wrapper.object as! AnyObject) {
// Found it!
found = true
break
}
}
if found == false {
// If not found then add the wrapper for this event
var updatedWrappers = storedWrappers
updatedWrappers.append(wrapper)
self.objects[event] = updatedWrappers
}
} else {
self.objects[event] = [wrapper]
}
}
func dispatch(event: KeyType) {
// Enumerate through wrappers
if let storedWrappers = objects[event] {
var idxToRemove = [Int]()
var currentIdx = 0
for storedWrapper in storedWrappers {
// if there is object to dispatch - dispatch message
// otherwise add index of this object to remove wrapper later
if let storedObject = storedWrapper.object {
storedObject.dispatcherDidDispatchEvent(event) /// <- cannot invoke 'this method' with an argument list of type '(KeyType)'
} else {
idxToRemove.append(currentIdx)
}
currentIdx++
}
// enumerate through reversed array of indexes to remove
// and remove items, update wrappers at the end.
idxToRemove = idxToRemove.reverse()
var updatedWrappers = storedWrappers
for idx in idxToRemove {
updatedWrappers.removeAtIndex(idx)
}
objects[event] = updatedWrappers
}
}
}
// EXAMPLE
enum CustomEvent {
case Start, Stop
}
class CustomListener<T: Hashable>: EventDispatcherProtocol {
func dispatcherDidDispatchEvent(event: T) {
println("CustomListener heard that event! \(event)")
}
}
// Create listeners and wrap them
var listener1 = CustomListener<CustomEvent>()
var listener2 = CustomListener<CustomEvent>()
// Create dispatcher
var dispatcher = EventDispatcher<CustomListener<CustomEvent>>()
dispatcher.add(listener: listener1, forEvent: CustomEvent.Start)
dispatcher.add(listener: listener2, forEvent: CustomEvent.Stop)
dispatcher.dispatch(CustomEvent.Start)
dispatcher.dispatch(CustomEvent.Stop)