簡體   English   中英

在變量的didSet中調用可選函數是否不好?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM