Swiftui 迅捷联合收割机

Swiftui 迅捷联合收割机,swiftui,combine,Swiftui,Combine,我正在跟踪一个消息。从27:45左右开始,讲师尝试基于布尔值设置变量,最后在init(task:task)中生成以下代码: 这对我来说太复杂了。首先,我找不到在struct对象上使用.map的文档,只在数组上使用。其次,这个&cancelables的东西是什么?(它在init{}之前定义为private var cancelables=Set())第三,为什么要使用这些代码,而不仅仅是: task.completionStateIconName = task.isCompleted ? &quo

我正在跟踪一个消息。从27:45左右开始,讲师尝试基于布尔值设置变量,最后在
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"
   }
}