基礎(chǔ)篇-ObjectC繼承沥割、類(lèi)別耗啦、屬性


前言

?? ?在實(shí)際的開(kāi)發(fā)過(guò)程中,繼承和類(lèi)別都會(huì)得到很多用處机杜。對(duì)于界面相似度很高的情況下帜讲,使用繼承可以節(jié)省很多代碼和設(shè)置,只需要在子類(lèi)中重寫(xiě)父類(lèi)中的方法椒拗,或者增加新的子類(lèi)方法即可似将,代碼非常的簡(jiǎn)潔維護(hù)起來(lái)也很方便。下面小節(jié)下相關(guān)的知識(shí)蚀苛,供需要的朋友查看在验。? ? 在Objective-C中,給一個(gè)類(lèi)擴(kuò)展一個(gè)其它方法堵未,有兩種實(shí)現(xiàn)方式:類(lèi)別和繼承腋舌。


?繼承

?這個(gè)是面向?qū)ο笳Z(yǔ)言都有的一個(gè)特性,子類(lèi)會(huì)繼承父類(lèi)的方法屬性以及成員變量渗蟹。? 這里說(shuō)的方法需要在 父類(lèi)中的 .h中聲明侦厚,子類(lèi)才可以使用super 調(diào)用父類(lèi)的方法,可以繼承過(guò)來(lái)父類(lèi)的一切屬性拙徽,可以使用父類(lèi)的成員變量刨沦。

? ? .h 文件相當(dāng)于一個(gè)對(duì)外公開(kāi)的 head ,是因?yàn)?oc 中無(wú)法導(dǎo)入 .m 文件膘怕,只能導(dǎo)入.h 文件想诅,所有子類(lèi)中需要用到父類(lèi)中導(dǎo)入的頭文件的話,這個(gè)頭文件需要在 父類(lèi)的.h? 中導(dǎo)入岛心,子類(lèi)無(wú)法調(diào)用 父類(lèi) .m 中導(dǎo)入的頭文件 和聲明的 成員變量来破。所以把 .m 文件中的東西相當(dāng)于是 私有的,不會(huì)被非本類(lèi)的對(duì)象所調(diào)用忘古。

? ? ?在繼承中需要注意的是:重寫(xiě)的這個(gè)方法在父類(lèi)中執(zhí)行時(shí)會(huì)替換掉原來(lái)的方法的(就算子類(lèi)中沒(méi)有調(diào)用這個(gè)新重寫(xiě)的方法徘禁,這個(gè)新方法也已經(jīng)被執(zhí)行了),一般自己不調(diào)用這個(gè)重寫(xiě)的方法髓堪,子類(lèi)一般只調(diào)用新加的方法送朱。

? 在 .h 中聲明成員變量娘荡,又不想被子類(lèi)調(diào)用,可以對(duì)這個(gè)成員變量進(jìn)行限定如:

@private

NSMutableArray*modelArray;

@private 私有成員驶沼,只有當(dāng)前類(lèi)可以訪問(wèn)炮沐;

@protected 受保護(hù)成員,只有當(dāng)前類(lèi)或子類(lèi)可以訪問(wèn)(如果沒(méi)有添加任何修飾則默認(rèn)為@protected)回怜;

@public 公共成員大年,所有類(lèi)均可訪問(wèn);


類(lèi)別category

這是Objective-C語(yǔ)言的一個(gè)特性玉雾,可以在不改變類(lèi)名和原來(lái)類(lèi)的實(shí)現(xiàn)的前提下翔试,實(shí)現(xiàn)對(duì)類(lèi)的方法擴(kuò)展。

以下兩種方式最好使用類(lèi)別复旬。

1)針對(duì)系統(tǒng)提供的一些類(lèi)遏餐,例如:NSString,NSArray,NSNumber等類(lèi),進(jìn)行方法擴(kuò)充的時(shí)候赢底。

2)類(lèi)別支持開(kāi)發(fā)人員針對(duì)自己構(gòu)建的類(lèi)失都,把相關(guān)的方法分組到多個(gè)單獨(dú)的文件中,對(duì)于大型而復(fù)雜的類(lèi)幸冻,這有助于提高可維護(hù)性粹庞,并簡(jiǎn)化單個(gè)源文件的管理。

對(duì)于以下情況洽损,無(wú)法使用類(lèi)別庞溜,必須使用繼承。

1)新擴(kuò)展的方法與原方法同名碑定,但是還需要使用父類(lèi)的實(shí)現(xiàn)流码。因?yàn)槭褂妙?lèi)別,會(huì)覆蓋原類(lèi)的實(shí)現(xiàn)(繼承也會(huì)覆蓋延刘,就是所謂的重寫(xiě)漫试,但是可以在重寫(xiě)的時(shí)候調(diào)用 ?父類(lèi)的同名方法,而類(lèi)別不能)碘赖,無(wú)法訪問(wèn)到原來(lái)的方法驾荣。

2)擴(kuò)展類(lèi)的屬性,這個(gè)類(lèi)別無(wú)法做到普泡。

OC中的子類(lèi)可以擁有和父類(lèi)相同名稱(chēng)的方法播掷,在子類(lèi)調(diào)用時(shí),優(yōu)先去自己的內(nèi)部尋找撼班,如果沒(méi)有則一層一層的往上找;

(4)OC語(yǔ)言是單繼承語(yǔ)言歧匈。在OC語(yǔ)言中,基本上所有類(lèi)的根類(lèi)都是NSObject類(lèi)砰嘁。

提示:重寫(xiě)即子類(lèi)重新實(shí)現(xiàn)了父類(lèi)中的某個(gè)方法件炉,覆蓋了父類(lèi)以前的實(shí)現(xiàn)勘究。

提示:每個(gè)類(lèi)中都有一個(gè)super class指針,該指針指向自己的父類(lèi)妻率。對(duì)象中有一個(gè)isa指針,該指針指向調(diào)用該對(duì)象的類(lèi)板祝。

繼承的好處:

(1)抽取出了重復(fù)的代碼

(2)建立了類(lèi)和類(lèi)之間的聯(lián)系

繼承的缺點(diǎn):耦合性太強(qiáng)

屬性

在OC中定義變量宫静,可以自己來(lái)定義變量的setter方法來(lái)設(shè)置變量值,用getter方法來(lái)獲取變量值,但是當(dāng)變量數(shù)量增多時(shí)券时,還采用手動(dòng)添加setter/getter方法來(lái)操作變量孤里,就會(huì)使得程序代碼量大大增加,于是就出現(xiàn)了 @property 來(lái)快速聲明設(shè)置獲取變量的值的方法,這也許就是 ?@property @synthesize/@dynamic 設(shè)計(jì)的本意橘洞。

@property是給編輯器看的捌袜。就算你不聲明@property,在obj的@implenmention下寫(xiě)好valueA和setValueA炸枣,還是可以obj.valueA賦值或取值虏等,但是沒(méi)有自動(dòng)聯(lián)想。

只聲明@property而不去實(shí)現(xiàn)适肠,在Xcode4.4以后會(huì)自動(dòng)幫你生成get和set方法

本質(zhì)上來(lái)講霍衫,屬性也會(huì)幫你定義一個(gè)成員變量,并根據(jù)屬性的聲明自動(dòng)生成getter/setter 方法侯养,其中setter 方法根據(jù)屬性(property)的屬性(attribute)來(lái)提供不同的內(nèi)存管理策略敦跌。

@property是一個(gè)屬性訪問(wèn)聲明以及聲明getter,setter方法

擴(kuò)號(hào)內(nèi)支持以下幾個(gè)屬性:(getter=getterName逛揩,setter=setterName柠傍,設(shè)置setter與getter的方法名,retain,copy辩稽,assign.......)

在聲明property屬性后惧笛,有2種實(shí)現(xiàn)選擇

@synthesize? 作用是實(shí)現(xiàn)屬性的,如getter,setter方法. (通過(guò)類(lèi)別和runtime 的對(duì)相關(guān)聯(lián)技術(shù)生成新的屬性時(shí)逞泄,無(wú)法使用這個(gè)這個(gè)設(shè)置徐紧,只能使用@dynamic)

編譯器期間,讓編譯器自動(dòng)生成getter/setter方法炭懊。

當(dāng)有自定義的存或取方法時(shí)并级,自定義會(huì)屏蔽自動(dòng)生成該方法

@dynamic

告訴編譯器,不自動(dòng)生成getter/setter方法侮腹,避免編譯期間產(chǎn)生警告

然后由自己實(shí)現(xiàn)存取方法

如果@synthesize和@dynamic都沒(méi)寫(xiě)嘲碧,那么默認(rèn)的就是@syntheszie var = _var;

我們來(lái)看一下屬性的本質(zhì)和進(jìn)化過(guò)程:

原始形態(tài)

? ? 定義一個(gè)實(shí)例變量:int age;

? ? 先在.h文件中聲明setter和getter器

? ? -(void)setAge:(int)newAge;

? ? ?-(int)age;

然后在.m文件中具體實(shí)現(xiàn)

-(void)setAge:(int)newAge

{

? ? ?age=newAge;

}

-(int)age

{

?return?age;

}

這樣的話就可以跟屬性一樣使用了。

//比如上面的聲明是一個(gè)Person類(lèi)

Person*person=[[Person?alloc]init];

[person?setAge:13];

int age=[person?age];

//點(diǎn)調(diào)用

person.age=13;??//.調(diào)用出現(xiàn)在=號(hào)左邊父阻,相當(dāng)于setter

intage=person.age???//.調(diào)用出現(xiàn)在=號(hào)的右邊愈涩,相當(dāng)于getter

NSLog(@"%i",person.age);//這也是getter


setter和getter的改進(jìn)寫(xiě)法:

每次要為一個(gè)屬性寫(xiě)上getter和setter望抽,不得不手十分麻煩,所以有了更簡(jiǎn)單的寫(xiě)法履婉,

在.h文件里煤篙,直接這樣寫(xiě),表示聲明了一個(gè)實(shí)例屬性和它的getter和setter器

@property?int?age;

然后在.m文件中這樣寫(xiě)毁腿,

@synthesize?age;

表示實(shí)現(xiàn)setteer和getter辑奈,這樣,就可以和以前一樣調(diào)用getter和setter了已烤。


setter和getter的改進(jìn)優(yōu)化:

可以看到鸠窗,getter器的方法名直接就是變量名,方法名和變量名一樣胯究,容易讓人迷糊稍计,所以,可以這樣優(yōu)化裕循。

在.h文件中依然這樣聲明

@property?int?age;

在.m文件中臣嚣,這樣去寫(xiě),

@synthesizeage=_age;?//加上一個(gè)_

//這么剥哑,我們就可以去使用_age???和使用age一樣

-(void)show

{

NSLog(@"%i",_age);

}

可以看出來(lái)茧球,在Objective-C中setter器沒(méi)什么區(qū)別,不過(guò)getter器的方法名缺少了get星持,因?yàn)間et...在Objective-C有別的用處抢埋,所以getter器直接寫(xiě)的就是變量名。

? ? ?1. 如果只聲明一個(gè)屬性a督暂,不使用@synthesize實(shí)現(xiàn):編譯器會(huì)使用_a作為屬性的成員變量(如果沒(méi)有定義成員變量_a則會(huì)自動(dòng)生成一個(gè)私有的成員變量_a揪垄;如果已經(jīng)定義了成員變量_a則使用自定義的成員變量_a。注意:如果此時(shí)定義的成員變量不是_a而是a則此時(shí)會(huì)自動(dòng)生成一個(gè)成員變量_a逻翁,它跟自定義成員變量a沒(méi)有任何關(guān)系)饥努;

? ? ? 2.如果聲明了一個(gè)屬性a,使用@synthesize a進(jìn)行實(shí)現(xiàn)八回,但是實(shí)現(xiàn)過(guò)程中沒(méi)有指定使用的成員變量(例如上面birthday):則此時(shí)編譯器會(huì)使用a作為屬性的成員變量(如果定義了成員變量a酷愧,則使用自定義成員變量;如果此時(shí)沒(méi)有定義則會(huì)自動(dòng)生成一個(gè)私有的成員變量a缠诅,注意如果此時(shí)定義的是_a則它跟生成的a成員變量沒(méi)有任何關(guān)系)溶浴;

? ? ? 3.如果聲明了一個(gè)屬性a,使用@synthesize a=_a進(jìn)行實(shí)現(xiàn)管引,這個(gè)過(guò)程已經(jīng)指定了使用的成員變量:此時(shí)會(huì)使用指定的成員變量作為屬性變量士败;(那還不如不寫(xiě)這個(gè)?@synthesize ..)

有了上面的總結(jié),相信理解上面的代碼并不難,通常在實(shí)際開(kāi)發(fā)過(guò)程中我們要么直接在@property中聲明不使用@synthesize谅将;要么使用過(guò)程中指定具體的成員變量漾狼。

此外再次強(qiáng)調(diào)一下,通過(guò)上面的方式定義變量的本質(zhì)還是生成對(duì)應(yīng)的gettter饥臂、setter方法(只是這個(gè)步驟編譯器幫你完成了)逊躁,如果通過(guò)@property定義了屬性,同時(shí)在.m中又自定義實(shí)現(xiàn)了對(duì)應(yīng)方法隅熙,則會(huì)使用自定義方法稽煤。


定義setter的語(yǔ)義

nonatomic??禁止多線程,變量保護(hù)猛们,提高性能念脯。

atomic ? ?是Objc使用的一種線程保護(hù)技術(shù)狞洋,基本上來(lái)講弯淘,是防止在寫(xiě)未完成的時(shí)候被另外一個(gè)線程讀取,造成數(shù)據(jù)錯(cuò)誤吉懊。而這種

機(jī)制是耗費(fèi)系統(tǒng)資源的

assign ? 此標(biāo)記說(shuō)明設(shè)置器直接進(jìn)行賦值 庐橙,賦值特性,不涉及引用計(jì)數(shù)借嗽,弱引用對(duì)基礎(chǔ)數(shù)據(jù)類(lèi)型 (NSInteger态鳖,CGFloat)和C數(shù)據(jù)類(lèi)型(int, float,double, char)等等。

如果你要一個(gè)屬性使用assign恶导,且這個(gè)類(lèi)符合NSCopying協(xié)議.

retain ? ?對(duì)其他NSObject和其子類(lèi)對(duì)參數(shù)進(jìn)行release舊值浆竭,再retain新值,新對(duì)象的引用計(jì)數(shù)+1惨寿;

指定retain會(huì)在賦值時(shí)喚醒傳入值的retain消息邦泄。此屬性只能用于Objective-C對(duì)象類(lèi)型,而不能用于Core

Foundation對(duì)象裂垦。(原因很明顯顺囊,retain會(huì)增加對(duì)象的引用計(jì)數(shù),而基本數(shù)據(jù)類(lèi)型或者Core Foundation對(duì)象都沒(méi)有引用計(jì)數(shù)——譯者注)蕉拢。

注意: 把對(duì)象添加到數(shù)組中時(shí)特碳,引用計(jì)數(shù)將增加對(duì)象的引用次數(shù)+1。

copy ? 對(duì)NSString 它指出晕换,在賦值時(shí)使用傳入值的一份拷貝午乓。拷貝工作由copy方法執(zhí)行闸准,此屬性只對(duì)那些實(shí)行NSCopying協(xié)議的對(duì)象類(lèi)型有效硅瞧,表示兩個(gè)對(duì)象內(nèi)容相同,新的對(duì)象retain為1 恕汇,與舊有對(duì)象的引用計(jì)數(shù)無(wú)關(guān)腕唧。

weak? ? weak比assign多了一個(gè)功能或辖,當(dāng)對(duì)象消失后自動(dòng)把指針變成nil,好處不言而喻枣接。弱引用除了不決定對(duì)象的存亡外颂暇,其他與強(qiáng)引用相同。即使一個(gè)對(duì)象被持有無(wú)數(shù)個(gè)若引用但惶,只要沒(méi)有強(qiáng)引用指向他耳鸯,那麼其還是會(huì)被清除。

retain? ?是指針拷貝膀曾,copy 是內(nèi)容拷貝县爬。

iOS 5 中對(duì)屬性的設(shè)置新增了strong 和weak關(guān)鍵字來(lái)修飾屬性(iOS 5 之前不支持ARC)

strong ? 用來(lái)修飾強(qiáng)引用的屬性,一塊內(nèi)存(一個(gè)對(duì)象)當(dāng)沒(méi)有 strong 類(lèi)型的指針指向它時(shí),它就會(huì)被釋放添谊;ARC中使用财喳,與MRC中retain同義,使用之后斩狱,計(jì)數(shù)器+1耳高。

官方文檔中有這樣的示例代碼:// The following declaration is a synonym for: @property(retain) MyClass *myObject;@property(strong) MyClass *myObject;表示了strong和retain是同義詞。

weak? ? 用來(lái)修飾弱引用的屬性所踊,當(dāng)一塊內(nèi)存(一個(gè)對(duì)象)被釋放時(shí)泌枪,指向它的 weak 類(lèi)型指針就會(huì)被釋放并賦值為 nil。

所以秕岛,如果一般情況下碌燕,我們都不希望字串的值跟著str變化,所以我們一般用 copy 來(lái)設(shè)置string的屬性继薛。如果希望字串的值跟著賦值的字串的值變化修壕,可以使用 strong,retain惋增。當(dāng)然這也只是針對(duì) NSMutableString叠殷,因?yàn)槿绻?NSString 那么 copy 與 retain 的效果是一樣的。

這里需要提一下诈皿,如果一個(gè)對(duì)象作為屬性時(shí)林束,定義setter的語(yǔ)義使用了copy字段,那么需要遵循 <NSCopying>協(xié)議稽亏,并且需要重寫(xiě) copyWithZone 方法壶冒。否則會(huì)cash。

NSZone 是蘋(píng)果對(duì)內(nèi)存分配和釋放的優(yōu)化方式截歉。NSZone不是一個(gè)對(duì)象胖腾;它是一個(gè)難懂的C結(jié)構(gòu),它被用于紀(jì)錄關(guān)于內(nèi)存處理(管理)一系列對(duì)象的信息。

- (id)copyWithZone:(NSZone*)zone

{

? ? id ? copy = [[[self ?class]alloc]init];

? ?if(copy){

? ? // self.imageName 是 當(dāng)前的屬性

? ? ?[copy ? setImageName:[self.imageName copyWithZone:zone]];

? ?}

? ? ? ?return ? copy;

}

一些需要注意的知識(shí)

1.實(shí)例方法/動(dòng)態(tài)方法

2.靜態(tài)方法/類(lèi)方法

靜態(tài)方法在堆上分配內(nèi)存(釋放工作由程序員控制)咸作,實(shí)例方法在棧上(是由編譯器自動(dòng)管理

靜態(tài)方法常駐內(nèi)存锨阿,實(shí)例方法不是,所以靜態(tài)方法效率高但占內(nèi)存



本文參考文章:

OC基礎(chǔ)相關(guān)

屬性相關(guān)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末记罚,一起剝皮案震驚了整個(gè)濱河市墅诡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌桐智,老刑警劉巖末早,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異说庭,居然都是意外死亡然磷,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)刊驴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)姿搜,“玉大人,你說(shuō)我怎么就攤上這事缺脉』居” “怎么了悦穿?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵攻礼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我栗柒,道長(zhǎng)礁扮,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任瞬沦,我火速辦了婚禮太伊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逛钻。我一直安慰自己僚焦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布曙痘。 她就那樣靜靜地躺著芳悲,像睡著了一般。 火紅的嫁衣襯著肌膚如雪边坤。 梳的紋絲不亂的頭發(fā)上名扛,一...
    開(kāi)封第一講書(shū)人閱讀 49,806評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音茧痒,去河邊找鬼肮韧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弄企。 我是一名探鬼主播超燃,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼拘领!你這毒婦竟也來(lái)了淋纲?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤院究,失蹤者是張志新(化名)和其女友劉穎洽瞬,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體业汰,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡伙窃,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了样漆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片为障。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖放祟,靈堂內(nèi)的尸體忽然破棺而出鳍怨,到底是詐尸還是另有隱情,我是刑警寧澤跪妥,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布鞋喇,位于F島的核電站,受9級(jí)特大地震影響眉撵,放射性物質(zhì)發(fā)生泄漏侦香。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一纽疟、第九天 我趴在偏房一處隱蔽的房頂上張望罐韩。 院中可真熱鬧,春花似錦污朽、人聲如沸散吵。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)矾睦。三九已至,卻和暖如春颓芭,著一層夾襖步出監(jiān)牢的瞬間顷锰,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工亡问, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留官紫,地道東北人肛宋。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像束世,于是被迫代替她去往敵國(guó)和親酝陈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容