類的老祖宗 - NSObject ,你真的了解?

前言

好吧,裝逼成功吸引你們進(jìn)來,我主要就是扯扯NSObject的API,大大小小分散在很多類中的類別我就不闡述了,主要就是NSObject 這個類,哦順便提下,我當(dāng)前Xcode7.2 ,iOS9.2,如有版本差異導(dǎo)致API不同的另說。

我們都知道NSObject自身遵循NSObject這個協(xié)議,從協(xié)議開始說

協(xié)議

  • - (BOOL)isEqual:(id)object

  • 對比對象之間是否相同,地址相同,hash值也要相同,才會返回YES

  • @property (readonly) NSUInteger hash / + (NSUInteger)hash

  • 一般用來比較,注意:新創(chuàng)建的實例之間一般不同,類的靜態(tài)方法返回值是一樣的,比如有個類叫Man ,[Man hash]值是相同的,Man *man = [Man new]; [man hash]值不同

  • @property (readonly) Class superclass / + (Class)superclass

  • 返回父類的類名

  • - (Class)class / + (Class)class

  • 返回自己的類名

  • **- (instancetype)self **

  • 返回自身,相當(dāng)于Java 中的this

  • - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2

  • 執(zhí)行aSelector方法,帶參數(shù),與[class do]這種方式比較,編譯不會報錯,只會警告,運行時檢查是否有該方法,如沒有,crash

  • ** - (BOOL)isProxy**

  • 檢查是否不繼承自NSObject(比如NSProxy),返回NO說明繼承

  • - (BOOL)isKindOfClass:(Class)aClass

  • 是否屬于aClass類或者aClass子類的成員

  • ** - (BOOL)isMemberOfClass:(Class)aClass**

  • 是否屬于aClass類的成員

  • ** - (BOOL)conformsToProtocol:(Protocol)aProtocol **
    *+ (BOOL)conformsToProtocol:(Protocol )protocol

  • 是否遵循protocol協(xié)議

  • ** - (BOOL)respondsToSelector:(SEL)aSelector**
    + (BOOL)instancesRespondToSelector:(SEL)aSelector

  • 是否實現(xiàn)了aSelector方法

  • **@property (readonly, copy) NSString description **
    *+ (NSString )description

  • 返回實例類名 和 地址,可重寫

  • ** @property (readonly, copy) NSString *debugDescription **
    + (NSString )debugDescription

  • 在調(diào)試時使用po命令使用,默認(rèn)實現(xiàn)description方法,一般用于實現(xiàn)更為具體的類描述,比如內(nèi)存地址等

自身方法

  • + (void)load

  • 運行時加載到這個類會調(diào)用(有且僅有一次),可用來操作Swizzling Method ,調(diào)用順序是父類load ->自身load->分類load,在load中最好不要調(diào)用其他類,因為很可能其他類還沒加載結(jié)束

  • ** + (void)initialize**

  • 第一次調(diào)用這個類的時候會觸發(fā)(有且僅有一次),比如[class new] ,[class alloc]。

  • - (instancetype)init

  • 不多說了,用爛了的方法

  • ** + (instancetype)new**

  • 相當(dāng)于[class alloc]init ,簡單初始化的時候可以直接new,支持點語法

  • *+ (instancetype)allocWithZone:(struct _NSZone )zone

  • 由于歷史原因遺留下來的方法,一般不主動調(diào)用,alloc 的時候會觸發(fā)這個方法

  • ** + (instancetype)alloc**

  • 返回一個已經(jīng)分配好的內(nèi)存對象 ,最好采用 [class alloc]init 這種二段式寫法,不然可能會有未知的問題,巧神說的

  • - (void)dealloc

  • MRC時代很重要,用于類銷毀的時候釋放,清空一些變量,ARC時代基本不用重寫,除了一些計時器的銷毀或者通知的移除等等。

  • - (void)finalize

  • 一些垃圾回收的事,一般不主動調(diào)用

  • ** - (id)copy**

  • 不可變的拷貝,需要實現(xiàn)copyWithZone

  • - (id)mutableCopy

  • 可變的拷貝
    @property (copy) NSMutableArray *array 或
    NSMutableArray *array = [array copy]是錯誤的 ,經(jīng)過copy,array變成了不可變的,后續(xù)操作會引發(fā)crash

  • **- (IMP)methodForSelector:(SEL)aSelector **
    + (IMP)instanceMethodForSelector:(SEL)aSelector

  • 獲取aSelector方法指針,用法:頻繁調(diào)用某個方法,可以利用這自己組裝成方法,提高性能

  • - (void)doesNotRecognizeSelector:(SEL)aSelector

  • 手動制造crash。用法:父類提供純虛函數(shù),比如A中有個方法
    - (void)show
    {
    // Subclasses need to override this method...
    [self doesNotRecognizeSelector:_cmd];
    }
    那么繼承A的子類,想要實現(xiàn)show方法,必須重寫,直接調(diào)用的話crash。

  • ** - (BOOL)allowsWeakReference **
    ** - (BOOL)retainWeakReference**

  • OC中有一些類,并不支持ARC,例如NSMachPort類??梢酝ㄟ^此方法來判斷是否支持ARC

  • + (BOOL)isSubclassOfClass:(Class)aClass

  • 類方法:判斷是否是某個類或其子類,作用于isKindOfClass一致。

有關(guān)消息轉(zhuǎn)發(fā)
unrecognized selector sent to instance,這種錯誤應(yīng)該不少見,調(diào)用了類不存在的方法導(dǎo)致Crash,在崩潰前我們有三次機(jī)會挽救一下

1.自救(動態(tài)增加方法)
  • (BOOL)resolveInstanceMethod:(SEL)sel
2.轉(zhuǎn)發(fā)其他類
  • (id)forwardingTargetForSelector:(SEL)aSelector
3.形成簽名然后轉(zhuǎn)發(fā)
  • (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
  • (void)forwardInvocation:(NSInvocation *)anInvocation

詳情見Demo

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

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

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