一种轻量级的基于事件的编程方法
在开发使用诸如 Model-View-Viewmodel 架构的应用程序时,当需要知道对象中的值何时更改,或者仅仅是想要拥有一个基于通知的 API 时,我发现使用像 NotificationCenter
这样的 API 很难编写好的单元测试来验证执行是否发生。此外,使用这些现有的 API 会助长不使用单向数据流的不良实践。
您可以使用 CocoaPods,通过将其添加到您的 Podfile
文件中来安装 SGSwiftyBind
platform :ios, '9.0'
use_frameworks
target 'MyApp' do
pod 'SGSwiftyBind'
end
您可以使用 Carthage,通过将其添加到您的 Cartfile
文件中来安装 SGSwiftyBind
github "eman6576/SGSwiftyBind"
您可以使用 Swift Package Manager,通过将正确的描述添加到您的 Package.swift
文件中来安装 SGSwiftyBind
import PackageDescription
let package = Package(
name: "YOUR_PROJECT_NAME",
dependencies: [
.package(url: "https://github.com/eman6576/SGSwiftyBind.git", from: "1.0.0")
],
targets: [
.target(
name: "YOUR_TARGET_NAME",
dependencies: [
"SGSwiftyBind"
])
]
)
注意:此仓库包含一个 examples 目录,其中包含关于如何使用此库的不同示例。我们建议您尝试这些示例。同时,请查看单元测试以了解库的实际应用。
要访问可用的数据类型,请像这样将 SGSwiftyBind
导入到您的项目中
import SGSwiftyBind
SGSwiftyBind
使用泛型来存储不同的数据类型
let intBind: SGSwiftyBind<Int> = SGSwiftyBind(1)
let doubleBind: SGSwiftyBind<Double> = SGSwiftyBind(1.2)
let stringBind: SGSwiftyBind<String> = SGSwiftyBind("Hello World")
您甚至可以使用您自己的自定义类型
protocol Animal {
var age: Int { get }
init(age: Int)
func makeSound()
func increaseAge()
}
struct Dog: Animal {
var age: Int
init(age: Int) {
self.age = age
}
func makeSound() {
print("Bark")
}
func increaseAge() {
age += 1
}
}
let dog = Dog(age: 3)
let animalBind: SGSwiftyBind<Animal> = SGSwiftyBind(dog)
使用 SGSwiftyBind 的一个很好的用例是了解变量何时更改或某些事件发生。让我们修改我们的 Animal
协议以使用 SGSwiftyBind
protocol Animal {
var age: SGSwiftyBindInterface<Int> { get }
init(age: Int)
func makeSound()
func increaseAge()
}
struct Dog: Animal {
var age: SGSwiftyBindInterface<Int> {
return ageBind.interface
}
private let ageBind: SGSwiftyBind<Int>
init(age: Int) {
ageBind = SGSwiftyBind(age)
}
func makeSound() {
print("Bark")
}
func increaseAge() {
ageBind.value += 1
}
}
我们修改了我们的 Animal
协议,使其在 age
属性上具有绑定器接口。我们的 Dog
类将需要更新其 age
属性以返回绑定器接口,并添加了一个名为 ageBind
的私有绑定器,类型为 SGSwiftyBind<Int>
。现在让我们使用我们的 Dog
对象
let dog = Dog(age: 3)
dog.age.bind({ (newAge) in
print("This is the dog's new age: \(newAge)")
}, for: self)
dog.makeSound()
dog.increaseAge()
在示例中,我们分配了一个 Dog
实例。然后,我们在 age 属性上注册一个绑定器,以便在值更改时,我们可以获取新值并对其进行一些操作。在我们的例子中,我们将值打印到控制台。
Dog
实例上的 age
属性的类型是 SGSwiftyBindInterface<Int>
而不是 SGSwiftyBind<Int>
。这背后的想法是为了外部不能改变 ageBind
的状态。这是一个例子
let currentAge = dog.age.value // We can retrieve the current value of age
dog.age.value = currentAge // The complier would give us an error stating that `age.value` is a get-only property
一旦我们完成了在 Dog
实例上使用绑定器,我们应该执行一些清理并像这样移除它
dog.age.unbind(for: self)
我们还可以获取已注册特定绑定器的当前观察者数量
let observerCount = dog.age.observerCount
请参阅贡献文件!
接受 PR。
小提示:如果编辑 Readme,请遵守 standard-readme 规范。