[英]Is it bad practice to call an optional function inside didSet of a variable?
我一直在尋找一種在變量更新時自動更新UI的簡便方法。 常規的KVO是如此雜亂的代碼,因此我一直在研究RxSwift,ReactiveCocoa等,但是發現它們很難掌握,並且有很多新對象以及太多不需要的東西。
我一直在研究變量的didSet
,以及對象中的emtpy可選函數。 希望它比解釋起來容易:
一個自定義對象(一個viewModel)
class AwesomeViewModel{
var awesomeText:String { didSet { updateBlock?() } }
var updateBlock:(()->())?
init(awesomeText:String){
self.awesomeText = awesomeText
}
}
和自定義的UIView:
class AwesomeView:UIView{
@IBOutlet weak var awesomeLabel: UILabel!
func bindViewModel(viewModel:AwesomeViewModel){
viewModel.updateBlock = { [weak self] in
self?.awesomeLabel.text = viewModel.awesomeText
}
viewModel.updateBlock?()
}
}
假設此自定義視圖AwesomeView
作為出口存在於UIViewController
中。 我創建一個AwesomeViewModel
實例,然后調用self.awesomeView.bindViewModel(awesomeViewModel)
。
稍后,當我在UIViewController
(或在其他任何地方,可以將其傳遞)執行awesomeViewModel.awesomeText = "Hello World"
,viewModel的變量didSet將觸發可選函數updateBlock
。 由於此功能已由自定義視圖AwesomeView
,它將自動更新該視圖中標簽中的文本。
我以為這很酷,而且很容易理解,但是是否有任何副作用,或者我沒有看到? 這是不好的做法嗎? 這似乎比使用具有所有功能和觀察功能的標准KVO容易得多。
我正在考慮將其用於UITableViewCell
,在cellForRowAtIndexPath
中將調用bindViewModel()
。 我認為沒有任何保留周期或任何保留周期,但我不太擅長發現它們。
在將這種方法應用到我的應用程序之前,我希望對此方法有一些優缺點-只是發現它是世界上最愚蠢的想法。 但是對我來說似乎還可以。
我相信學習RxSwift是一個好主意。 但是與此同時,您所做的大部分都很好。 這種方法的局限性在於您只能使用一個回調。 RxSwift將允許對一個Observable的任意數量的訂閱。 我事先表示歉意,這個答案是基於觀點的。
我將更改updateBlock
以將“觀察到的”值作為參數,即
var updateBlock: ((String) -> ())?
因為這可以幫助避免保留周期,並且也許重命名updateBlock
可以更准確地反映哪個值已更改,即
var awesomeTextUpdate: ((String) -> ())?
但是,@ rmaddy是正確的,這會使您希望觀察到具有多種屬性的痛苦。 這可以用屬性及其值的枚舉部分解決,例如
class AwesomeViewModel {
enum Property {
case awesomeText(String)
case awesomeNumber(Int)
}
}
並將updateBlock
更改為具有類型
var updateBlock: ((AwesomeViewModel.Property) -> ())?
和didSet
到
var awesomeText: String {
didSet {
updateBlock?(.awesomeText(awesomeText))
}
}
然后客戶可以簡單地switch
Property
枚舉。 打破他們不在乎的地方,進入他們在哪里的地方。 如果您具有許多可能可觀察到的屬性,但在特定情況下客戶端僅需要一個,則可能會很痛苦。
如果似乎沒有正確的折衷辦法,那主要是因為沒有妥協,RxSwift可能是更好的長期解決方案。 但是,如果您不會廣泛復制此范例,則可以使用可選函數。 記住:不要重復自己。
tl; dr您正在做的事情看起來很合理,但是擴展性不好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.