Swiftui 迅捷联合收割机
我正在跟踪一个消息。从27:45左右开始,讲师尝试基于布尔值设置变量,最后在Swiftui 迅捷联合收割机,swiftui,combine,Swiftui,Combine,我正在跟踪一个消息。从27:45左右开始,讲师尝试基于布尔值设置变量,最后在init(task:task)中生成以下代码: 这对我来说太复杂了。首先,我找不到在struct对象上使用.map的文档,只在数组上使用。其次,这个&cancelables的东西是什么?(它在init{}之前定义为private var cancelables=Set())第三,为什么要使用这些代码,而不仅仅是: task.completionStateIconName = task.isCompleted ? &quo
init(task:task)
中生成以下代码:
这对我来说太复杂了。首先,我找不到在struct对象上使用.map
的文档,只在数组上使用。其次,这个&cancelables
的东西是什么?(它在init{}
之前定义为private var cancelables=Set()
)第三,为什么要使用这些代码,而不仅仅是:
task.completionStateIconName = task.isCompleted ? "checkmark.circle.fill" : "circle"
这似乎给出了相同的结果,但是第一个代码片段有效,而第二个无效吗?$task
(带有$
前缀)是@Published
属性包装器的投影值,它返回一个类型的变量。换句话说,它是一个联合发布器,每当属性(在本例中为Task
)更改时,它都会发布一个值
如果您没有了解联合框架(或其他反应式框架),那么这个答案肯定是不够的。在高层,联合发布器会发出值,您可以通过.map
之类的运算符进行转换,并最终订阅,例如使用.sink
或.assign
因此,逐行:
// a publisher of Task values
$task
// next, transform Task into a String using its isCompleted property
.map { task in
task.isCompleted ? "circle.fill" : "circle"
}
// subscribe, by assigning the String value to the completionStateIconName prop
.assign(to: \.completionStateIconName, on: self)
现在,上面返回了anycancelable
的一个实例,您需要在接收值时保留该实例。因此,您需要将其直接存储为属性,或者使用.store
将其添加到集合中,这是一种常见的方法
那么,为什么它如此复杂?这可能是为了在task
属性发生更改时,合并管道将更新completionStateIconName
属性而构建的
如果你刚刚做了:
completionStateIconName = task.isCompleted ? "circle.fill" : "circle"
这将在刚开始时分配值
这就是说,在这种特殊情况下,使用Combine实际上可能不必要地过于复杂,而仅使用didSet
:
var task: Task {
didSet {
completionStateIconName ? task.isCompleted ? "circle.fill" : "circle"
}
}
假设任务
是一个结构
,那么didSet
就可以正常工作了。但计算属性var completionStateIconName:String{completionStateIconName?task.isCompleted?“circle.fill”:“circle”}
也是如此。通过查看视频的其余部分,我们可以看到他甚至没有将TaskCell
转换为使用completionStateIconName
,因此根本没有理由引入该属性@robmayoff,我还没有看完整的视频,但是是的-似乎在该视频中使用Combine是一种不必要的过度使用,因为任务是@Published
,如果它被视图使用,只使用计算属性就可以了。@NewDev@rob谢谢。我忘了提出我的一行作为didSet
或计算值的一部分,但实际上我是这么想的。感谢您花时间如此完整地回答。我知道联合收割机,但肯定不知道@罗布,我想你的三元表达式中有一个额外的片段,不是吗?你的意思是不是仅仅var completionStateIconName:String{task.isCompleted?“circle.fill”:“circle”}
?我将继续这个视频和后续视频,看看是否有必要使用Combine。。。
var task: Task {
didSet {
completionStateIconName ? task.isCompleted ? "circle.fill" : "circle"
}
}