您可能需要一个else
条款,不过,清除文本字段,如果weather
是nil
。同样,如果您可能会从后台线程更新它,您可能需要将该UI更新发送回主线程。
请注意,当您在单元格的init
中设置了weather
(不管怎样,在此时将配置@IBOutlet
也不会调用此观察者)。所以请确保你不依赖于此。
此外,如果Weather
是可变的,则认识到如果更改现有Weather
对象的fromDate
,则不会捕获该对象。 (如果Weather
是可变的,你真的想通过KVO,委托协议模式或你有什么来捕捉它的变化属性。)但是如果你使Weather
不变,你应该没问题。
所以,从技术上说,这就是问题的答案,但是这引起了一些设计方面的考虑:
一个一般应尽量使不同类型的松耦合,即一种不应该过于依赖另一个人的内部行为。但是在这里我们有一个观察者,这个观察者依赖于Weather
的可变性。
这种使用存储属性在视图内存储模型对象是不可取的。单元格在屏幕外滚动时可以重复使用,但您可能需要一个单独的模型来捕获相关的模型对象,然后控制器根据需要处理向视图对象(单元格)提供适当的模型对象。
底线,不建议在“视图”中使用存储属性作为“模型”信息。
您可以通过编写代码来解决这两个问题,这些代码清楚地表明您仅仅使用此参数来更新UI控件,而不是用于存储任何内容。因此,而一个存储的属性,我只想用一个方法:
func updateWithWeather(weather: Weather?) {
if let weather = weather {
dayLabel.text = dayFormatter.stringFromDate(weather.fromDate)
// ... more code like this
} else {
dayLabel.text = nil
// ... more code like this
}
}
而这很可能只是从collectionView:cellForItemAtIndexPath:
内调用。
但是,这表明你只是更新基于天气参数的控件,而不是试图做任何事情。而巧合的是,天气对象的可变性现在是不相关的,因为它应该是。如果型号改变,请致电reloadItemsAtIndexPaths:
,这将触发您的collectionView:cellForItemAtIndexPath:
被调用。
有些时候,didSet
观察员存储的财产是一种有用的模式。但是,只有当房产确实是一种看法时才应该这样做。例如,考虑绘制某种形状的自定义视图。您可能已经存储了指定例如绘制路径时要使用的笔划的宽度和颜色的属性。然后,存储lineWidth
和strokeColor
的属性可能是有意义的,然后您可能会有一个didSet
调用setNeedsDisplay()
(这会触发重新绘制视图)。
因此,您建议的模式确实具有实际应用,只是应该将其限制在属性是视图对象属性的情况。
来源
2015-12-17 00:06:53
Rob
感谢您的反馈。你有另外一种方法可以做得更好吗?除了用你描述的要点改进代码。 – LuckyLuke
奥基,谢谢。在那之前,我留下了“未答复”的问题。 – LuckyLuke
@LuckyLuke - 顺便说一句,除了单元格和'Weather'之间不可靠的紧密耦合之外,使用存储属性存储模型信息的想法也是不可取的。看修改后的答案, – Rob