iOS-屬性與實(shí)例變量(成員變量)

在我看來iOS開發(fā)中屬性和實(shí)例變量是兩個(gè)概念,還是有一定區(qū)別的:

1. 只聲明實(shí)例變量,類外部不可訪問,不可賦值,類內(nèi)部可以通過self->屬性名或者屬性名訪問和賦值

2. 聲明并實(shí)現(xiàn)實(shí)例變量的setter方法和getter方法,類外部和內(nèi)部都可以通過類.實(shí)例變量名(本質(zhì)上就是調(diào)用實(shí)例變量的setter方法和getter方法)訪問和賦值

2.1 iOS5之前為了避免麻煩聲明實(shí)例變量的setter和getter方法,可通過@property聲明屬性對(duì)應(yīng)聲明實(shí)例變量,

@property相當(dāng)于聲明了實(shí)例變量的setter方法和getter方法,成對(duì)出現(xiàn)的@synthesize相當(dāng)于實(shí)現(xiàn)實(shí)例變量的setter方法和getter方法

2.2 iOS5之后系統(tǒng)推薦使用如下用法,編譯器會(huì)自動(dòng)生成一個(gè)名為_屬性名的實(shí)例變量與屬性相對(duì)應(yīng)(在沒有寫@synthesize的情況下)

注意:如果你添加了@synthesize 屬性名 那么_屬性名就不存在了,聲明和實(shí)現(xiàn)的就是名為屬性名的實(shí)例變量的setter和getter方法

如果.m文件中需要同時(shí)重寫實(shí)例變量的setter和getter方法時(shí),在方法里使用_屬性名會(huì)報(bào)錯(cuò),因?yàn)槟阒貙憣?shí)例變量的setter和getter方法后,_屬性名就不存在了和添加@synthesize同一個(gè)道理,你可以添加@synthesize 屬性 = _屬性 這樣你就可以在setter和getter方法中使用_屬性名了,或者重寫_屬性的setter和getter方法(如下,不推薦使用)

3.category中的屬性和成員變量

面試的時(shí)候經(jīng)常會(huì)被問到“類別可以擴(kuò)展屬性嘛?”,面對(duì)這個(gè)問題不同工作年限的人回答的不一樣。剛剛從事iOS的人可能立刻回答不能,然后面試官很詭異的偷偷一笑就繼續(xù)下面一個(gè)面試題了,很明顯你要是這么回答你就可能已經(jīng)掉坑里了??,對(duì)類別有一定了解的人就會(huì)了解,類別并不是不可以擴(kuò)展屬性的,只不過類別中不可以添加成員變量(實(shí)例變量)而已。

3.1 類別中添加@property描述的屬性,這時(shí)候編譯是沒問題的沒警告沒報(bào)錯(cuò),但是一旦在創(chuàng)建對(duì)象后為屬性賦值或者使用這個(gè)屬性的時(shí)候,程序就崩潰了,奔潰的原因也很簡(jiǎn)單,就是找不到屬性的set/get方法。

那我們就按照這個(gè)流程來,在類別中為屬性添加set/get方法,在set方法里面賦值的時(shí)候找不到賦值的對(duì)象,也就是說系統(tǒng)沒有為我們生成帶下劃線的成員變量,沒生成我們就自己加,??一加就報(bào)錯(cuò)??磥磉@才是類別不能擴(kuò)展屬性的根本原因。

但是辦法都是人想出來的嘛!不能用實(shí)例變量的話我就用全局變量保存屬性的值就好了,沒想到還真可以,創(chuàng)建對(duì)象后可以賦值,可以獲取值。

利用runtime里面的class_copyPropertyList()獲取類的所有property,這個(gè)屬性居然也在里面,但是使用class_copyIvarList()的時(shí)候卻沒有對(duì)應(yīng)的成員變量,也就是說針對(duì)這個(gè)屬性,系統(tǒng)沒有生成對(duì)應(yīng)的成員變量。當(dāng)然這種方法只是用來學(xué)習(xí)的,真正開發(fā)中估計(jì)會(huì)用到另一種辦法:利用runtime的關(guān)聯(lián)對(duì)象。

runtime中的關(guān)聯(lián)對(duì)象說的簡(jiǎn)單點(diǎn)就是利用鍵值對(duì)的方式為兩個(gè)對(duì)象建立關(guān)聯(lián)關(guān)系,詳細(xì)的資料可以查看iOS runtime 關(guān)聯(lián)對(duì)象。

3.2 類別中添加成員變量,這種方式XCode直接給你報(bào)錯(cuò)了:Instance Value may not be placed in the categories。很直接了當(dāng)?shù)母嬖V你類別中不能放置實(shí)例變量,至于原因就需要從runtime中去了解了,我也只是了解了皮毛,至于細(xì)節(jié)可以查看runtime詳解。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容