Swift 中具有绑定通用变量的通用函数
generic function with binding generic variable in Swift
任何人都可以解释下面泛型 class“活动”与此绑定变量一起使用的具体作用吗?下面也提到了 3 个例子,但我真的不清楚它是如何工作的
class Active<T> {
var bind :(T) -> () = { _ in }
var value :T {
didSet {
bind(value)
}
}
init(_ v :T) {
value = v
}
}
示例:
- var user = Active("")
- var 计数 = 活动 (64)
- var status = Active(true)
具体示例如下所示link
https://levelup.gitconnected.com/2-ways-to-execute-mvvm-ios-5c47d60ebcd0
您给出了使用不同类型的值实例化 Active
的示例(说明了一般行为)。但是你没有利用 Active
提供的“观察者”模式。
让我们看看你会如何使用 Active
:
let foo = Active(0)
foo.bind = { value in
print(value)
}
foo.value = 1 // the closure will be called, printing the value
foo.value = 42 // the closure will be called again
想法是你实例化对象,用你自己的替换bind
闭包,然后每次改变值时都会调用闭包。
这种“观察者”模式的优点是 Active
提供了一种机制(在这个原始示例中是一个简单的闭包)来允许其他对象观察值的变化。这是 MVVM 的核心准则之一(正如您引用的那篇文章试图传达的那样),即您可以编写代码,例如,根据模型的更改自动更新视图。
如果您熟悉完成处理程序,那么这对您来说非常有意义。考虑一个带有准系统完成处理程序的函数:
func someFunction(completion: () -> Void) {
completion()
}
someFunction {
print("completion")
}
完成处理程序没有参数,因此用 completion()
调用它并且闭包的捕获列表 someFunction { ... }
是空的。但是,如果我们要向这个完成处理程序添加一个参数,那么它将使用参数 completion(true)
调用,并且闭包必须定义其捕获列表 someFunction { (done) in ... }
.
func someFunction(completion: (_ done: Bool) -> Void) {
completion(true)
}
someFunction { (done) in
print(done)
}
如果我们不关心完成处理程序中的布尔值,那么我们可以在闭包的捕获列表中忽略它:
someFunction { _ in
print("completion")
}
这就是 bind
的意思,一个带有单个参数的闭包,它的捕获列表不关心传递给它的参数。
var bind: (T) -> Void = { _ in }
所以想法是用一个值实例化Active
,然后给bind
一个闭包,每当值改变时执行。因此,当它发生变化时,您已经将一些任务绑定到该值的变化上。
// instantiate
var count = Active(64)
// bind its change to a closure
count.bind = { _ in
// perhaps update the UI?
}
// later when the value changes, the closure is called and
// whatever task you had in the closure is executed
count.value = 128
并且,作为旁注,T
只是一个任意字母(它可以是 </code>)用作实际使用的任何类型的占位符(即<code>Int
, Bool
) 当此对象被实例化时。无论 T
是什么,在整个对象的使用过程中它必须是同一类型。
任何人都可以解释下面泛型 class“活动”与此绑定变量一起使用的具体作用吗?下面也提到了 3 个例子,但我真的不清楚它是如何工作的
class Active<T> {
var bind :(T) -> () = { _ in }
var value :T {
didSet {
bind(value)
}
}
init(_ v :T) {
value = v
}
}
示例:
- var user = Active("")
- var 计数 = 活动 (64)
- var status = Active(true)
具体示例如下所示link
https://levelup.gitconnected.com/2-ways-to-execute-mvvm-ios-5c47d60ebcd0
您给出了使用不同类型的值实例化 Active
的示例(说明了一般行为)。但是你没有利用 Active
提供的“观察者”模式。
让我们看看你会如何使用 Active
:
let foo = Active(0)
foo.bind = { value in
print(value)
}
foo.value = 1 // the closure will be called, printing the value
foo.value = 42 // the closure will be called again
想法是你实例化对象,用你自己的替换bind
闭包,然后每次改变值时都会调用闭包。
这种“观察者”模式的优点是 Active
提供了一种机制(在这个原始示例中是一个简单的闭包)来允许其他对象观察值的变化。这是 MVVM 的核心准则之一(正如您引用的那篇文章试图传达的那样),即您可以编写代码,例如,根据模型的更改自动更新视图。
如果您熟悉完成处理程序,那么这对您来说非常有意义。考虑一个带有准系统完成处理程序的函数:
func someFunction(completion: () -> Void) {
completion()
}
someFunction {
print("completion")
}
完成处理程序没有参数,因此用 completion()
调用它并且闭包的捕获列表 someFunction { ... }
是空的。但是,如果我们要向这个完成处理程序添加一个参数,那么它将使用参数 completion(true)
调用,并且闭包必须定义其捕获列表 someFunction { (done) in ... }
.
func someFunction(completion: (_ done: Bool) -> Void) {
completion(true)
}
someFunction { (done) in
print(done)
}
如果我们不关心完成处理程序中的布尔值,那么我们可以在闭包的捕获列表中忽略它:
someFunction { _ in
print("completion")
}
这就是 bind
的意思,一个带有单个参数的闭包,它的捕获列表不关心传递给它的参数。
var bind: (T) -> Void = { _ in }
所以想法是用一个值实例化Active
,然后给bind
一个闭包,每当值改变时执行。因此,当它发生变化时,您已经将一些任务绑定到该值的变化上。
// instantiate
var count = Active(64)
// bind its change to a closure
count.bind = { _ in
// perhaps update the UI?
}
// later when the value changes, the closure is called and
// whatever task you had in the closure is executed
count.value = 128
并且,作为旁注,T
只是一个任意字母(它可以是 </code>)用作实际使用的任何类型的占位符(即<code>Int
, Bool
) 当此对象被实例化时。无论 T
是什么,在整个对象的使用过程中它必须是同一类型。