swift-event

License: MIT

C# 事件 启发,在 Swift 中简化观察者模式实现的类。

此包基于以下原则构建:

  1. 通用性:每个类都支持泛型。

  2. 简单性:受 C# 事件启发,swift-event 支持订阅(通过 +=subscribe())、取消订阅(通过 -=unsubscribe())以及通过 invoke 通知。

  3. 封装性invoke 在声明范围之外不可访问,防止其他类破坏内部逻辑。

安装 - 快速入门 - 示例 - 文档 - 问答 - 变更日志

安装

Swift Package Manager

您可以使用 Swift Package Manager 来安装 swift-event,方法是添加正确的描述。

到您的 Package.swift 文件

dependencies: [
        .package(url: "https://github.com/MarcAlx/swift-event.git", from: "1.0.1"),
    ]

或者通过 Xcode

从您的 .xcodeproj 文件中选择您的项目,然后转到 Swift Packages 选项卡,然后添加(通过 +):https://github.com/MarcAlx/swift-event.git

复制源代码

您可以在这里找到源代码:https://github.com/MarcAlx/swift-event/blob/master/Sources/swift-event/swift_event.swift

所有注释的代码都小于 100 行,只需复制并粘贴到您的代码中即可。

快速入门

0. 导入包

import swift_event

1. 创建一个事件

let tmp = Event<String>.create()
//tmp holds the event in 'event' and a pointer to 'invoke' method

2. 创建一个处理程序并订阅

var handler =  EventHandler<String>(handle: { sender, args in
    print(args)
})
tmp.event += handler

3. 触发事件

tmp.invoke(self,"Hello world !")
//handler should print "Hello world !"

4. (可选) 取消订阅

tmp.event -= handler

示例

快速示例

let tmp = Event<String>.create()
tmp.event += EventHandler<String>(handle: { sender, args in
    print(args)
})
tmp.invoke(self,"Hello world !")
//handler should print "Hello world !"

通过函数

let tmp = Event<String>.create()
let dispose = tmp.event.subscribe(EventHandler<String>(handle: { sender, args in
        print(args)
    })
)
tmp.invoke(self,"Hello world !")
//handler should print "Hello world !"
dispose()

在类内部

Test.swift

import swift_event

class Test {
    private var _somethingHappened:Event<String>
    public var somethingHappened: Event<String> {
        return self._somethingHappened
    }
    
    private var _somethingHappenedInvoke:Delegate<String>
    
    public init() {
        let tmp = Event<String>.create()
        self._somethingHappened = tmp.event
        self._somethingHappenedInvoke = tmp.invoke
    }
    
    public func doSomething() {
        self._somethingHappenedInvoke(self, "Hello !")
    }
}

用法

var test = Test()

var handler = EventHandler<String>(handle: {sender, args in print(args)})

test.somethingHappened += handler

test.doSomething() //should raise event, thus leading in an handler call

test.somethingHappened -= handler

test.doSomething() //should print nothing, as handler has been unsubscribe

文档

文档也以 .doccarchive 的形式提供,其中包括一些交互式教程,位于:./Doc/swift-event.doccarchive

class Event<T>

static func create() -> (invoke:Delegate<T>,event:Event<T>)

创建一个 Event 并返回它以及它的 invoke 方法。

注意: 这是实例化 Event 的唯一方法,这样只有调用此方法的类才能访问 invoke。

返回: 一个元组,包含创建的 Event 以及指向其私有 invoke 的指针。

operator overload +=

通过添加处理程序来订阅事件

operator overload -=

通过删除处理程序取消订阅事件

func subscribe (handler: EventHandler<T>)-> () -> Void

通过添加处理程序来订阅事件

注意: += 的简写

parameter handler: 要添加的 EventHandler

返回: 一个函数,它是 -= 的简写,方便取消订阅

func unsubscribe (handler: EventHandler<T>) -> Void

通过删除处理程序取消订阅事件

注意: -= 的简写

class EventHandler<T>

类型化 Event 的类型化 EventHandler

注意: 因为 Swift 不允许通过 === 判断 func 是否相等,所以需要这个类。

var handle:Delegate<T>

将处理事件的 Delegate

init(handle:@escaping Delegate<T>)

实例化一个新的类型化 EventHandler

parameter handle: 用于处理事件的关联 Delegate

typealias Delegate<T> = (_ sender:AnyObject?,_ args:T) -> Void

Event 委托的简写

parameter sender: 事件的发送者

parameter args: 事件参数

问答

Q. 为什么 EventHandler 是一个类而不是 func 的类型别名?

A. 因为在 swift 中,func 不可 equatable 并且不支持 ===,因此无法实现 unsubscribe-= 运算符。

Q. 为什么 Event.init() 不能是私有的?

A. 为了避免在创建范围之外调用 invoke()。(比如 c# 中的 invoke()

贡献

您可以通过 pull request 为此 repo 做出贡献,请确保遵循此 repo 的理念并更新文档。

变更日志

1.0.0

包的第一个版本。