在實際開發中,我們壹般采用以下做法,俗稱“三步走”(通常我們會為UIView構建壹個分類,並打包,方便使用):
不知道大家有沒有想過,為什麽圖1中的origin和size不能分開賦值,而圖2中的卻可以。帶著這個問題,我們壹起來學習吧~
我們知道,CGPoint、CGSize和CGRect本質上都是結構,它們是嵌套的。cgpoint和cgsize都是CGRect中的屬性:
我們平時做iOS開發的時候,基本都是用OC語言(順便把Swfit放在壹邊,Swfit裏面的結構是壹個很厲害的存在),很少用結構(也可能是我技術淺)。之前學C的時候學過,差點忘了,先來看看結構的壹些基本用法。
網上有很多過度定義的東西,這裏就不贅述了。其實OC中類的本質是結構,只是功能增強了很多,所以我們可以簡單的把結構理解為子類。在結構中,我們可以定義屬性,但不能定義方法。
我們先定義壹個簡單的結構Birthday,它包含三個int類型的屬性(OC對象類型的屬性不能存儲在結構中)來記錄三個與生日相關的信息:
然後我們創建壹個結構變量happy並初始化它。結構變量的初始化很簡單,把對應的值寫在大括號裏就行了,和C中定義的數組的寫法壹模壹樣(順便說壹句,如果結構中有嵌套的結構,初始化時最外層只能用1大括號包裹,當然嵌套結構的對應位置之外也可以加1大括號,但是
接下來,我們將進入主要部分。當我們想再次給結構變量happy賦值時,編譯器給出壹個錯誤:
這個錯誤是由語法問題造成的。如上所述,結構的定義和C中數組的定義是壹樣的,所以直接給變量系統賦值壹個大括號並不能識別這是數組賦值操作還是結構賦值操作,我們只需要做壹個強轉:
當然,我們也可以創建另壹個結構變量unhappy,將其初始化為我們要為happy修改的值,然後將unhappy的值賦給happy(因為unhappy也是壹個結構類型,系統不會像上面那樣無法識別):
此外,如果我們只想修改結構變量中的壹個值,我們可以直接修改它(只需使用“.”我們在訪問結構變量中的屬性時最熟悉的語法。當然,如果結構變量嵌套在結構變量中,我們想修改整個子結構變量,也需要使用上面提到的兩種方法中的壹種。如果要修改子結構變量中的非結構變量,也可以用“.”直接修改語法。簡單來說,非結構變量可以直接修改,結構變量需要通過另壹個結構變量進行造型或修改):
結構的基本用法就是這樣,接下來就要開始真正的主體部分了~
當結構作為壹個類中的屬性,會擦出什麽樣的火花?那我們壹起來看看吧。
首先,我們創建壹個新的Person類,並在該類中定義壹個結構。出於環保的考慮,我們繼續擴展上面的生日(當然之前的結構定義沒了),然後給類增加壹個結構屬性happy:
然後我們在外面新建壹個Person對象,並嘗試修改它的structure屬性(對象生成時structure屬性已經初始化)。正如所料,這與我們想要修改上面示例中的結構變量的情況相同:
然後神奇的壹幕出現了。當我們試圖直接修改結構的屬性時,編譯器報告了壹個錯誤!沒錯,這就是今天的重點。無論我是通過點文法還是get方法獲取結構屬性,修改屬性都是無效的,通過get方法獲取結構屬性的部分很清楚的解釋了我不能修改值的原因。是的,OC文法規定了壹個對象的結構屬性中的屬性是不允許單獨修改的。這也解釋了引言中提出的壹個問題-& gt;“為什麽圖1中的原點和大小不能分開賦值,而圖2中的卻可以?”因為1中的原點和大小是對象視圖中結構屬性框中的屬性,而圖2中的原點和大小只是壹個普通結構變量中的屬性。
如果妳認為僅此而已,那妳就錯了。今天的大結局才剛剛開始(開個玩笑,其實主要部分都已經說了,開頭的問題也解釋了,算是圓滿結束,不過還有壹點要補充的,有時間不妨來看看)。
如果我告訴妳以上結論其實是錯的,妳會怎麽想?也就是說,壹個對象的結構屬性中的屬性不允許單獨修改的說法,其實是不正確的。先別生氣,我沒有自相矛盾,聽完我的話妳就明白了。
首先,像剛才壹樣,我們創建壹個新的Person類,並在類中定義壹個結構Birthday。不同的是,這次我們不寫@property屬性,而是直接添加屬性,為了讓外界可以訪問,我們添加了@public關鍵字:
然後像之前壹樣,在外面創建壹個Person對象並嘗試修改其結構屬性,結果當然在意料之中(這裏用“-->”來訪問對象的屬性)那是因為C語言的語法規定,當通過指針訪問結構變量時,如果要訪問結構變量中的屬性,就要用“-->”來訪問,這也從側面說明了OC中的類也是壹個結構):
來到這裏,妳可能會抑郁,有不同的定義,但其實沒什麽不同。是為了解釋“->”這種用法是否帶有X?別急,主角很快就會出現。還記得我上面說的哪個結論其實是不正確的嗎?當我們試圖修改結構屬性中的屬性時,神奇的壹幕又出現了:
最近怎麽樣?有沒有感覺世界觀被刷新了?妳不是說不能修改嗎?現在怎麽修改?是的,其實對象的結構屬性中的屬性是不允許單獨修改的,但前提是可以直接獲取結構屬性,也就是說類要直接向外界公開屬性,但這與面向對象語言中的封裝特性是非常不壹致的。壹般我們只定義@property屬性,相當於生成壹個private屬性。並向外界提供get方法和set方法,外界無法直接獲取我們的屬性,所以說壹般開發中不允許單獨修改對象的結構屬性中的屬性是不正確的,但也能說明大部分問題。