Swift3.0 KVO/KVC/通知的應用

寫作初衷:看了好多關于KVC/KVO/通知的相關文章,發(fā)現都是講理論,并且不太好理解,更不太好應用到自己的項目中。我自己總結了下它們三個,分別附了一個例子,希望對大家有所幫助~

一、KVC:Swift中使用KVC和KVO的類都必須必須繼承自NSObject

iOS很多UI控件會有很多隱藏的屬性,但是這些屬性,我們是可以通過kvc方式用的,不會被蘋果拒絕,善于使用隱藏的屬性,可以提高開發(fā)效率,其實kvc也是基于runtime實現的。

查看隱藏屬性的方式:

一:可以通過runtime打印出所有的隱藏屬性。
二:也可以用打斷點的方式,在調試區(qū)查看UI控件的隱藏屬性

// 用runtime的方式打印出所有UITextView的屬性
unsigned int count = 0;
    Ivar *ivars = class_copyIvarList([UITextView class], &count);
    for (int i = 0; i<count; i++) {
        Ivar ivar = ivars[i];

        NSLog(@"UITextView-屬性名:-->%s------%s", ivar_getName(ivar));
    }

kvc方式給對象的隱藏屬性賦值:

        textField.placeholder = "請輸入名字"
// forKey: 不支持屬性的屬性。最好用下面的方法:forKeyPath:
// textField.setValue(UIColor.red, forKey: "_placeholderLabel.textColor")
這句會報錯:'[<UITextField 0x105bdf2a0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key _placeholderLabel.textColor.' 
// 正確的方式:
 textField.setValue(UIColor.red, forKeyPath: "_placeholderLabel.textColor")
備注:即使是forKeyPath的方式,里面的屬性也不能寫一個沒有的屬性,否則還是會崩潰。:invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.
libc++abi.dylib: terminate_handler unexpectedly threw an exception

二、KVO: 當被觀察者的對象的屬性被修改的時候,會通知觀察者,KVC是KVO的基礎
        // WKWebView監(jiān)聽title (webView初始化的地方監(jiān)聽)
        webView.addObserver(self, forKeyPath: "title", options: .new, context: nil)

     // 監(jiān)聽title的回調
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if (keyPath == "title") {
                self.addTitle(titleString: self.webView.title!)
        }
    }
    
    deinit { // 必須在頁面銷毀的時候,remove
        webView.removeObserver(self, forKeyPath: "title")
    }

三、通知:需要被觀察者主動發(fā)送通知,然后觀察者注冊監(jiān)聽,比KVO多了發(fā)送通知的一步。優(yōu)點是:監(jiān)聽不局限屬性的變化,可以對多種多樣的狀態(tài)變化進行監(jiān)聽,范圍廣,靈活。
    // 觸發(fā)通知的地方:
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationTagDic object:dic];
    // 接收到通知的地方:
    [[[[NSNotificationCenter defaultCenter] rac_addObserverForName:kNotificationTagDic object:nil] takeUntil:[self rac_willDeallocSignal]] subscribeNext:^(id x) {
        NSDictionary *dic = [x object];
        if (dic && [dic isKindOfClass:[NSDictionary class]] && dic.count > 0) {
              
        }
    }];

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • KVC/KVO 概念 KVC : 即 Key-Value-Coding,用于鍵值編碼。作為 cocoa 的一個標準...
    滿臉胡茬的小碼農閱讀 1,984評論 2 8
  • 1.KVC 關于 KVC 和 KVO ,我之前的總結文章有寫過,但是趨于表面,沒有探究其內部真正的實現原理和進階用...
    Liberalism閱讀 1,117評論 0 5
  • 本文分為2個部分:概念與應用。概念部分旨在剖析 KVO 這一設計模式的實現原理;應用部分通過創(chuàng)建的項目,以說明 K...
    啊左閱讀 57,972評論 107 438
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結起來就是把...
    Dove_iOS閱讀 27,217評論 30 472
  • 世界上最遙遠的距離不是你在圈內我在圈外而是當我走進你的圈子時你已經處在更大的圈內
    拓桑閱讀 486評論 9 9