寫在開頭
很多人說寒哥不寫干貨 那今天寒哥就狠狠心 寫個(gè) (其實(shí)不是不寫 是太懶了 平時(shí)都寫在印象筆記中 因?yàn)槭墙o自己看的 格式比較散 要寫博客 就要認(rèn)認(rèn)真真的寫 怕誤了看官的眼 )
- 順便來個(gè)廣告
iOS開發(fā)者 群532084214 給大家提供一個(gè)交流技術(shù) 也可以聊天打屁的平臺(tái)
此文默認(rèn) 讀者有iOS開發(fā)經(jīng)驗(yàn) 包括OC Swift 和一點(diǎn)點(diǎn)的runtime的理解
先新建個(gè)項(xiàng)目 Swift 和oc都行
新建一個(gè)OCClass:NSObject
我們來聲明一個(gè)成員屬性
所有人都知道定義這都ivar的時(shí)候 系統(tǒng)會(huì)幫你做好幾件事
生成帶下劃線的私有成員屬性 對(duì)應(yīng) 的setter 和getter
那么我們來Swift中看一下怎么定義一個(gè)成員變量
so easy 這個(gè)誰不會(huì)嘛 (我這里不討論可選類型 而是討論 什么叫做存儲(chǔ)變量 什么叫做計(jì)算變量)
我們會(huì)在想 Swift 會(huì)不會(huì)像oc一樣 給我們同樣的生成了 setter 和getter呢
于是有的人會(huì)這樣寫
然后這樣調(diào)用
然后一運(yùn)行程序 Crash了 很多人 會(huì)說 肯定了 不就是循環(huán)調(diào)用
斷點(diǎn)出的堆棧信息 這樣的
很明顯 這就是循環(huán)調(diào)用了 但是你把self.去掉 之后再次運(yùn)行
還是崩
奶奶的要崩潰了 這是什么鬼
其實(shí)Swift設(shè)計(jì)的初衷和oc并不是特別一樣
后文解答
我們先來看一個(gè)mvc的結(jié)構(gòu)圖
其實(shí)在mvc中 View是不能拿到model的 他們互相不知道
但是在開發(fā)過程中 我們很多view的數(shù)據(jù)來源自model 如果我們?cè)谕獠刻峁┮粋€(gè)一個(gè)的屬性 然后等著控制器 去賦值 再在對(duì)應(yīng)的setter里面去 修改view 的顯示 我們會(huì)發(fā)現(xiàn)很累 因?yàn)橐粋€(gè)頁面可能有太多屬性 所以在大多數(shù)情況 我們?cè)趘iew聲明一個(gè)model的屬性 等值控制器去賦值
但是
但是
但是
重要的事情說三遍
我們這樣我違反了 mvc的思想 其實(shí)(mvvm)也是這樣的 view不能拿到model 因?yàn)槟隳玫搅薽odel 就可以修改 就會(huì)造成頁面中的數(shù)據(jù)不對(duì)應(yīng)
大風(fēng)險(xiǎn)啊
于是Swift中出現(xiàn)了 計(jì)算變量這種東西
- 什么叫計(jì)算變量 還有什么叫存儲(chǔ)變量 丛楚?
什么鬼
我們聲明了一種變量就是為了存儲(chǔ)數(shù)據(jù) 但是Swift中有一種特殊的變量 叫做 計(jì)算變量 這種變量是 不能存放數(shù)據(jù) (你特么又在逗我 )
看官 我真的沒逗你 是真的 這種變量主要就是為了 在view里面聲明一個(gè)只讀的變量 去來給頁面賦值的 例子
這種辦法就巧妙的 避開了以前在OC開發(fā)iOS時(shí) 可能對(duì)mvc造成的規(guī)則不符的情況
- 這里出現(xiàn)了其他的情況 就是我真的想擁有一個(gè)變量 還想在setter方法里面做些別的操作
這里我們出現(xiàn)了先入為主的觀念 很多java C++ 和OC開發(fā)者 都以為對(duì)于的setter就是對(duì)應(yīng)的Set方法 其實(shí)不是這樣的額
在Swift中訪問控制是有訪問控制關(guān)鍵字來決定的
如
對(duì)于的監(jiān)聽方法就變成了這樣
在早期 apple 建議開發(fā)者 都使用 view 使用kvo去觀察model的變化 來給對(duì)于的頁面賦值 但是也不知道程序員的習(xí)慣 還是如何 大家還是我行我素 就在view中拿到model
在Swift中 建議使用計(jì)算變量 來給view賦值
- 關(guān)于網(wǎng)上對(duì)于計(jì)算變量的寫法
很多人 都模仿 OC中的寫法 自己寫個(gè)帶下劃線的私有變量 然后提供 set和get方法 我只能說你根本就沒有理解Swift 帶著陳舊的思想去學(xué)習(xí) 多此一舉嘛
- 關(guān)于兩個(gè)問題
我真的想在計(jì)算屬性里面存值
屬性觀察期的位置 固定了 那以前的kvo怎么辦
還記得OC中的面試題嗎
category 聲明一個(gè)property 是什么意思
怎么給category增加成員屬性
在oc的category中寫了一個(gè)property 其實(shí)系統(tǒng)幫你做了一個(gè)對(duì)應(yīng)的set 和 get方法的聲明 具體也不會(huì)有私有變量生成 也不會(huì)有方法實(shí)現(xiàn) 如果你真的要加變量 就要用到kvo的 關(guān)聯(lián)對(duì)象 如果你對(duì)runtime不熟悉 去簡(jiǎn)述搜 runtime 很多好文章
在Swift中是這樣的
關(guān)于kvo Swift的初衷就是為了創(chuàng)造幾門極度安全化的語言 所以Swift不建議我們?cè)?使用kvo了 因?yàn)? 在oc中kvo 會(huì)產(chǎn)生 一個(gè)私有的中間類 (不懂去看runtime ) 在Swift 真的想用kvo 就要用黑魔法了
參看自喵神的tips
“在 Swift 中使用 KVO 有兩個(gè)顯而易見的問題。
首先是 Swift 的 KVO 需要依賴的東西比原來多。在 Objective-C 中我們幾乎可以沒有限制地對(duì)所有滿足 KVC 的屬性進(jìn)行監(jiān)聽,而現(xiàn)在我們需要屬性有 dynamic 進(jìn)行修飾耕漱。大多數(shù)情況下憨攒,我們想要觀察的類不一定是 dynamic 修飾的 (除非這個(gè)類的開發(fā)者有意為之,否則一般也不會(huì)有人愿意多花功夫在屬性前加上 dynamic稚失,因?yàn)檫@畢竟要損失一部分性能),并且有時(shí)候我們很可能也無法修改想要觀察的類的源碼飞袋。遇到這樣的情況的話戳气,一個(gè)可能可行的方案是繼承這個(gè)類并且將需”“要觀察的屬性使用 dynamic 進(jìn)行重寫。比如剛才我們的 MyClass 中如果 date 沒有 dynamic 的話授嘀,我們可能就需要一個(gè)新的 MyChildClass 了:”
最后再來個(gè)廣告 受到 公眾號(hào)主人邀請(qǐng) 我的文章也會(huì)被發(fā)布到這個(gè)公眾號(hào)
** 加個(gè)歡迎微信掃碼關(guān)注吧**