這個問題比較簡單,我想很多朋友都知道的一清二楚,當然也會有很多朋友只知道一點點(以初學者為主)。當初學ios的時候全篇點語法,後來看到說點語法要經過方法派發,比較慢,直接訪問例項變數比較快,於是又全篇直接訪問,再後來看到有人說過,寫入例項變數的時候用點語法,讀取例項變數的時候直接訪問就行。當初知識面比較窄,想著記住就ok。今天把這個問題翻出來驗證一番,也為以後學習ios的朋友提供個方便。
先放結論
這個結論正著好像不太好說,所以反過來說說直接訪問例項變數和使用點語法會帶來的一些相應問題⊙﹏⊙
1、直接訪問無法觸發kvo
2、直接訪問會繞過屬性的某些某些某些(重三遍)許可權修飾符(如copy)
3、在訪問器方法中使用點語法會導致遞迴
4、讀取變數值的時候一般可以直接訪問
5、貌似沒有了,等朋友們補充~
開始驗證(xue xi)
針對上面的幾點,本文主要驗證繞過某些屬性的許可權修飾符這一點,其他的幾點比較容易理解,在這裡就不驗證了。**比較簡單,不打算貼了,直接說說都有啥。首先有乙個person類、乙個dog類,person有兩個屬性:name(copy),dog(strong)。專案對main.m禁用arc方便列印retaincount,對兩個類要開啟arc。
然後我們先看看一般情況下我們使用點語法設定屬性值的情況
這裡簡單地把name的位址打出來了,方便大家理解。可以看到dog的retaincount是2,因為它是strong的,main中retain一次,person中又retain一次。再看name,屬性的位址和main中變數的位址不一樣,很簡單,因為它是copy的,所以retaincount = 1 。
接下來才是我們真正驗證的環節,我們來看看不適用點語法而直接訪問例項變數會是什麼樣
dog的retaincount依舊是2,看來直接訪問例項變數對dog沒有啥影響
再看name,奇怪的是它的retaincount也變成2了,再看位址,發現main中name和person中name的位址居然是一樣的,而我們對name屬性給的卻是copy。可見,使用直接訪問例項變數的方式,系統將不執行copy行為,而是變得跟strong是一模一樣。對於字串使用strong修飾會有什麼樣的危險我想大家都是知道的——容易被篡改。
那麼為什麼直接訪問會繞過copy,而不繞過我們給dog的strong修飾呢?其實呢,它都有繞過的。因為我們使用直接訪問例項變數就沒有經過屬性的訪問器,也就把屬性的許可權修飾符直接晾一邊了,並沒有使用它。雖然我們沒有使用屬性,但是系統依舊為我們合成了例項變數,而合成的時候給例項變數的修飾符是根據屬性的修飾符來的。但是,屬性有的修飾符例項變數不一定有,例項變數可以有strong、weak,但是它不會有copy,因為系統對於例項變數,可以自動為我們retain,但是沒法為我們自動執行深拷貝。所以copy在使用直接訪問的方式的時候被直接忽略,而strong和weak屬性因為例項變數也擁有相應修飾符而不會有任何問題。
再總結
所以,,當我們的屬性使用的是strong、weak這些例項變數也能夠擁有的修飾符的時候,是可以在設定例項變數的時候也直接訪問的,不會有問題,但是當我們使用copy這類例項變數沒有擁有的修飾符的時候,直接訪問是會出問題的,這時候就必須使用點語法。
什麼時候使用引用 什麼時候使用指標
使用引用引數的主要原因有兩個 程式設計師能修改呼叫函式中的資料物件 通過傳遞引用而不是整個資料 物件,可以提高程式的執行速度一般的原則 對於使用引用的值而不做修改的函式 如果資料物件很小,如內建資料型別或者小型結構,則按照值傳遞 如果資料物件是陣列,則使用指標 唯一的選擇 並且指標宣告為指向cons...
java中什麼時候使用this
對this的理解 this只存在於方法內部,用來代表呼叫改方法的物件。可以理解為每乙個方法內部都有乙個區域性變數叫this,每當初始化乙個物件時,就把該物件的位址傳遞給了該物件每乙個方法中的this變數,從而可以在方法內部使用這個的物件。public class demothis public vo...
ios 什麼時候呼叫layoutSubviews
今天在寫程式時候遇見layoutsubviews觸發時候引起的問題。特來總結一下什麼時候會觸發layoutsubviews layoutsubviews在以下情況下會被呼叫 1 init初始化不會觸發layoutsubviews 2 addsubview會觸發layoutsubviews 3 設定v...