分類
1彤断、你用分類都做了哪些事情野舶?
-聲明私有方法(比如定義一個(gè)分類,只有頭文件放到對應(yīng)宿主.m里宰衙,滿足私有方法的聲明和使用平道,不暴露具體實(shí)現(xiàn)。)
-分解體積龐大的類文件
-把Framework的私有方法公開
2供炼、特點(diǎn)
-運(yùn)行時(shí)決議一屋,指的是在運(yùn)行時(shí),通過runtime將分類里面的內(nèi)容添加到宿主類里面袋哼,當(dāng)我們在編寫或者編好分類文件后冀墨,它并沒有把寫好的內(nèi)容添加到宿主類上,這個(gè)時(shí)候宿主類還沒有分類中的方法涛贯,而是在運(yùn)行時(shí)通過runtime把分類中的方法添加至宿主類上轧苫,這是分類的最大特點(diǎn),也是分類和擴(kuò)展的最大區(qū)別。
-可以為系統(tǒng)類添加分類含懊,而擴(kuò)展是不能給系統(tǒng)類添加擴(kuò)展的身冬。
3、分類中都可以添加哪些內(nèi)容岔乔?
-實(shí)例方法
-類方法
-協(xié)議
-屬性(只聲明了get和set方法酥筝,并沒有實(shí)現(xiàn)get和set方法,也沒有生成實(shí)例變量)
4雏门、加載調(diào)用棧
-分類添加的方法可以“覆蓋”原類方法(當(dāng)然不是真的覆蓋)
-兩個(gè)分類嘿歌,里面有一個(gè)同名方法,最后編譯的分類里面的方法被調(diào)用茁影。
-名字相同的分類會(huì)引起編譯報(bào)錯(cuò)
擴(kuò)展
1宙帝、問題:一般用擴(kuò)展做什么?
-聲明私有屬性
-聲明私有方法
-聲明私有成員變量
2募闲、擴(kuò)展的特點(diǎn):
-編譯時(shí)決議(分類是運(yùn)行時(shí)決議)?
-只以聲明的形式存在步脓,多數(shù)情況下存在于宿主類的.m文件中(分類有聲明有實(shí)現(xiàn))
-不能為系統(tǒng)類添加擴(kuò)展(系統(tǒng)類可以添加分類)
代理:
是一種軟件設(shè)計(jì)模式(代理模式),并且可以添加屬性
iOS中以@protocol的形式體現(xiàn)
代理和通知的區(qū)別是:代理是一對一的傳遞方式浩螺,而通知是一對多的傳遞方式
delegate一般聲明為weak以規(guī)避循環(huán)引用靴患,這樣的結(jié)果是:
代理方----strong>委托方 同時(shí) 委托方-----weak>代理方
通知:
通知是使用 觀察者模式 來實(shí)現(xiàn)的用于跨層傳遞消息的機(jī)制
1、問:如何實(shí)現(xiàn)通知機(jī)制要出?
在通知中心鸳君,有一個(gè)Notification_Map字典,里面存儲(chǔ)著以通知名稱為key患蹂,觀察者組成的數(shù)組作為value
KVO
1或颊、什么是KVO?
-KVO是Key-value observing的縮寫
-KVO是Objective-C對觀察者設(shè)計(jì)模式的一種實(shí)現(xiàn)
-Apple使用了isa混寫(isa-swizzling)來實(shí)現(xiàn)KVO
當(dāng)觀察對象的某個(gè)屬性時(shí)(當(dāng)調(diào)用了addobserverforkeypath:),系統(tǒng)在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建一個(gè)子類(這樣是為了重寫這個(gè)類的setter方法),并且將對象的isa指針指向新創(chuàng)建的這個(gè)類彤叉,修改isa的指向就是isa指針混寫的一個(gè)標(biāo)志,即isa混寫技術(shù)
isa混寫技術(shù):
指的就是將isa指針動(dòng)態(tài)重新指向新的類
setter方法重寫的方法具體實(shí)現(xiàn):
2看铆、問:通過kvc設(shè)置value,kvo能否生效盛末?
可以弹惦,原因是因?yàn)镵VC改變屬性值,會(huì)進(jìn)入屬性值的setter方法悄但,從而觸發(fā)KVO
3棠隐、問:通過成員變量直接賦值value,kvo能否生效檐嚣?
不可以助泽,但是可以通過手動(dòng)修改setter方法啰扛,觸發(fā)KVO
或者添加[self willChangeValueForKey:@"name"]; [self didChangeValueForKey:@"name"]; 這句話就可以了
總結(jié):
使用setter方法改變值,KVO會(huì)生效
使用setValue:forKey:改變值嗡贺,KVO會(huì)生效
成員變量直接修改需手動(dòng)添加某些代碼隐解,KVO才會(huì)生效
KVC
1、KVC是Key-value coding的縮寫诫睬。
里面有兩個(gè)重要的方法:
- (id)valueForKey:(NSString *)key;
- (void)setValue:(nullable id)value forKey:(NSString *)key;
2煞茫、問:KVC是否有違面向?qū)ο笏枷?/p>
KVC只要知道某個(gè)對象的私有變量名稱key,可以在外部將其value進(jìn)行修改摄凡,也就是有違面向?qū)ο笏枷氲摹?/p>
valueForKey:的系統(tǒng)實(shí)現(xiàn)流程:
valueForKey:說白了就是通過一個(gè)key找到對應(yīng)的value
找value可以是通過getter方法找续徽,也可以通過直接找對應(yīng)的實(shí)例變量
也就是,一個(gè)是方法亲澡,一個(gè)是實(shí)例變量钦扭,兩種方法
圖中
Accessor Method is exist?
就是通過getter方法找,有的話直接調(diào)用
Instance Var is exist?
就是有沒有對應(yīng)的實(shí)例變量床绪,有的話調(diào)用
3客情、:Accessor Method(訪問器方法)如何找方法呢?
通過getKey会涎、key(正好是getter方法)裹匙、isKey三個(gè)方法瑞凑,如果有則YES
這三個(gè)都是方法
4末秃、:+(BOOL)accessInstanceVariablesDirectly的作用?
系統(tǒng)給我們提供了一個(gè)方法:
+(BOOL)accessInstanceVariablesDirectly籽御,默認(rèn)是返回YES
在返回YES的基礎(chǔ)上练慕,才會(huì)調(diào)用Instance Var is exist,判斷是否存在相應(yīng)的實(shí)例變量或者相似的實(shí)例變量
如果我們重寫該方法技掏,使其返回NO铃将,那么直接報(bào)沒有找到對應(yīng)的值處理;不再進(jìn)行實(shí)例變量的判斷哑梳。
5:Instance Var is exist?判斷規(guī)則是什么劲阎?
通過查找是否存在:_key、_isKey鸠真、key悯仙、isKey四個(gè)實(shí)例變量,如果有則YES
這四個(gè)都是實(shí)例變量
6吠卷、問:如果valueForKey:沒有找到對應(yīng)的value锡垄,會(huì)怎樣?
如果valueForKey:沒有找到對應(yīng)的value祭隔,會(huì)調(diào)用valueForUndefinedKey:
從而造成崩潰
YZPerson *person1 = [[YZPerson alloc] init];
NSLog(@"person1.age = %@", [person1 valueForKey:@"age"]);
7货岭、setValue:forKey:的系統(tǒng)實(shí)現(xiàn)流程:
屬性關(guān)鍵字
1、問:屬性關(guān)鍵字可以分為哪幾類?
讀寫權(quán)限:readonly千贯、readwrite(默認(rèn))
原子性:atomic(默認(rèn))屯仗、nonatomic
引用計(jì)數(shù)
setter\getter
atomic可以保證獲取和賦值是線程安全的
但是,并不能保證在使用過程中是線程安全的(例如對一個(gè)使用atomic修飾的數(shù)組進(jìn)行添加和刪除元素并不能保證是線程安全的丈牢,只是保證在獲取數(shù)組的值和賦值時(shí)是保證線程安全的)
引用計(jì)數(shù):
retain(非ARC)\strong(ARC中)
assign(既可以修飾基本數(shù)據(jù)類型祭钉,也可以修修飾對象類型)\unsafe_unretain(只有在MRC中使用頻繁,在ARC中基本不使用)
weak
copy
2己沛、問:assign和weak的區(qū)別有哪些慌核?
assign特點(diǎn)
可以修飾基本數(shù)據(jù)類型,如int申尼、BOOL等
可以修飾對象類型垮卓,但不改變其引用計(jì)數(shù)器
當(dāng)使用assign修飾對象,在對象釋放的時(shí)候师幕,指針仍然反向原對象地址粟按,會(huì)產(chǎn)生懸垂指針,如果繼續(xù)訪問原對象可能導(dǎo)致
出現(xiàn)內(nèi)存泄露或者程序異常霹粥。
3灭将、weak
不可以修飾基本數(shù)據(jù)類型
修飾對象類型,但不改變其引用計(jì)數(shù)器
當(dāng)使用weak修飾對象后控,在對象釋放的時(shí)候庙曙,會(huì)自動(dòng)置為nil
weak和assign的區(qū)別:assign既可以修飾基本類型,也可以修飾對象類型浩淘,weak只能修飾對象類型捌朴,第二個(gè)是assign修飾對象,在對象釋放的時(shí)候张抄,指針仍然反向原對象地址砂蔽,而weak在釋放以后被置為nil的。共同點(diǎn)是都不改變引用計(jì)數(shù)署惯。
4左驾、copy
淺拷貝
淺拷貝并沒有新建一塊內(nèi)存
淺拷貝對原來的對象引用計(jì)數(shù)+1
深拷貝會(huì)新建一塊內(nèi)存,與原來的內(nèi)存里面內(nèi)容一樣
深拷貝對原來的對象引用計(jì)數(shù)不變
深拷貝和淺拷貝的區(qū)別是否開辟了新的內(nèi)存空間极谊,是事影響了引用計(jì)數(shù)
對可變對象copy變?yōu)椴豢勺児钣遥⑶覟樯羁截?br>
對可變對象mutablecopy變?yōu)榭勺儯羁截?br>
總結(jié):
可變對象的copy和mutableCopy均為深拷貝
不可變對象的mutableCopy是深拷貝怀酷,copy為淺拷貝稻爬。
copy返回的均是不可變對象
如果賦值過來是NSMutableArray,copy后其實(shí)是NSArray蜕依,如果對其進(jìn)行添加或者刪除操作桅锄,會(huì)造成程序崩潰
5琉雳、
問:為何會(huì)做 _obj != obj 的判斷?不做可以嗎友瘤?
如果不做翠肘,則先進(jìn)行[_obj release];也就是原來的對象可能已經(jīng)被釋放掉了。再進(jìn)行[obj retain]操作辫秧,會(huì)造成程序異常束倍。