您可能需要一個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