一、分類
聲明私有方法
分解體積龐大的類文件
把framework私有方法公開
特點
運行時決議
為系統(tǒng)類添加分類
實例方法
類方法
協(xié)議
屬性(實際值生成了get和set方法)
分類添加的方法可以覆蓋原類的方法,名字相同的分類會引起編譯報錯
多個分類方法時最后編譯的最終生效,取決于編譯順序
能為分類添加成員變量,用關聯(lián)對象的技術給分類添加實例變量
objc_getAssociatedObject
objc_setAssociateObject
objc_removeAssociatedObjects
objc_AssociationPolicy //關聯(lián)策略
關聯(lián)對象由AssociationsManager管理并在AssociationsHasMap存儲
所有類的關聯(lián)對象內(nèi)容都在同一個全局容器中
如果關聯(lián)對象的值為nil會擦除上次已經(jīng)關聯(lián)的內(nèi)容
二、擴展
聲明私有屬性
聲明私有方法
聲明私有成員變量
分類和擴展的區(qū)別:編譯時決議,只以聲明的形式存在,多數(shù)情況下寄生于宿主類的m文件中,不能為系統(tǒng)類添加擴展
三、代理
代理是一種軟件設計模式,iOS以@protocol形式實現(xiàn)
傳遞方法是一對一的,通知則是一對多
代理的的協(xié)議聲明,協(xié)議定義委托方需要代理方實現(xiàn)的方法或者屬性,require必須實現(xiàn)的,optional可實現(xiàn)的,規(guī)避循環(huán)引用。
四、通知
是使用觀察者模式實現(xiàn)的,用于跨層傳遞消息的機制
傳遞方式一對多
五、KVO(key-value-observing)
kvo是觀察者模式的又一種實現(xiàn),使用isa混寫isa-swizzling(isa回寫技術)來實現(xiàn)kvo
比如A類系統(tǒng)會在運行時動態(tài)創(chuàng)建NSKVONotifying_A,將原來的類的isa指向新創(chuàng)建的類,重寫起setter方法,NSKVONotifying_A實際上是A類的一個子類。通過重寫setter方法負責通知所有觀察者對象
重寫setter方法中插入了willChangeValueForkey和didChangeValueForkey
通過kvc設置的value也能使kvo生效,應該會調(diào)用到對應的setter方法
通過成員直接賦值不能觸發(fā)kvo,因為沒有調(diào)用起setter犯法,可以調(diào)用willChangeValueForkey、didChangeValueForkey使其生效
六、KVC (key-value-coding)
valueForKey、setValueForKey
是會破壞面向對象的編程思想的
valueForKey的具體流程為:判斷get方法存在,直接調(diào)用get方法,不存在則通過+(Bool)accessInstanceVariablesDirectly的返回值確定要不要獲取對應的成員變量或相似的成員變量(getKey key isKey _key _getKey _isKey ),如果有則返回對應的值,如果沒有回調(diào)用valueForUndefineKey拋出NSUndefinedKeyException異常
setValueForKey的具體流程:是否有對應的set方法,存在直接賦值,如果不存在通過+(Bool)accessInstanceVariablesDirectly的返回值確定要不要設置對應的成員變量或相似的成員變量(setKey key isKey _key _setKey _isKey ),如果有則返回對應的值,如果沒有回調(diào)用setValueForUndefineKey拋出NSUndefinedKeyException異常
七、屬性關鍵字
讀寫權限:
readonly readwrite(默認)
原子性:
atomic(默認)賦值和獲取是相對線程安全的,對atomic的數(shù)組進行操作不能保證線程安全,
nonatomic
引用計數(shù):
retain(mrc中使用)、strong(arc中使用)
assign:可以用用來修飾基本數(shù)據(jù)類型,修飾對象不改變其引用計數(shù),會產(chǎn)生懸垂指針(指向曾經(jīng)存在的對象,但該對象已經(jīng)不再存在了,此類指針稱為懸垂指針)
weak:修飾對象不改變其引用計數(shù),所指向對象被釋放會被只為nil,只能修飾對象
unsafe_unretained:(mrc,在arc中基本已經(jīng)退出歷史舞臺了)
copy:淺拷貝會增加引用計數(shù),只對內(nèi)存地址進行復制,讓對象指針和原對象指針指向同一片內(nèi)存空間.深拷貝是內(nèi)容拷貝,不會影響引用計數(shù)??勺儗ο蟛还苁巧羁截愰_始淺拷貝都會進行深拷貝,copy之后返回的都是不可變對象。
@property(copy) NSMutableArray *array,如果賦值的是NSMutableArray copy后位NSArray 如果是NSArray copy后也是NSArray ,在調(diào)用array的添加方法時會報錯。
八、面試題
1、MRC下給重寫retain修飾屬性的setter方法,
-(void)setObj:(id)obj{
if(_obj != obj){//不是為了判斷重復對象多余開銷,而是如果 _obj 為nil下面的release會報錯
[_obj release];
_obj = [obj retain];
}
}