前言
好吧,裝逼成功吸引你們進來,我主要就是扯扯NSObject的API,大大小小分散在很多類中的類別我就不闡述了,主要就是NSObject 這個類,哦順便提下,我當前Xcode7.2 ,iOS9.2,如有版本差異導致API不同的另說。
我們都知道NSObject自身遵循NSObject這個協議,從協議開始說
協議
- (BOOL)isEqual:(id)object
對比對象之間是否相同,地址相同,hash值也要相同,才會返回YES
@property (readonly) NSUInteger hash / + (NSUInteger)hash
一般用來比較,注意:新創建的實例之間一般不同,類的靜態方法返回值是一樣的,比如有個類叫Man ,[Man hash]值是相同的,Man *man = [Man new]; [man hash]值不同
@property (readonly) Class superclass / + (Class)superclass
返回父類的類名
- (Class)class / + (Class)class
返回自己的類名
**- (instancetype)self **
返回自身,相當于Java 中的this
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2
執行aSelector方法,帶參數,與[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協議
** - (BOOL)respondsToSelector:(SEL)aSelector**
+ (BOOL)instancesRespondToSelector:(SEL)aSelector是否實現了aSelector方法
**@property (readonly, copy) NSString description **
*+ (NSString )description返回實例類名 和 地址,可重寫
** @property (readonly, copy) NSString *debugDescription **
+ (NSString )debugDescription在調試時使用po命令使用,默認實現description方法,一般用于實現更為具體的類描述,比如內存地址等
自身方法
+ (void)load
運行時加載到這個類會調用(有且僅有一次),可用來操作Swizzling Method ,調用順序是父類load ->自身load->分類load,在load中最好不要調用其他類,因為很可能其他類還沒加載結束
** + (void)initialize**
第一次調用這個類的時候會觸發(有且僅有一次),比如[class new] ,[class alloc]。
- (instancetype)init
不多說了,用爛了的方法
** + (instancetype)new**
相當于[class alloc]init ,簡單初始化的時候可以直接new,支持點語法
*+ (instancetype)allocWithZone:(struct _NSZone )zone
由于歷史原因遺留下來的方法,一般不主動調用,alloc 的時候會觸發這個方法
** + (instancetype)alloc**
返回一個已經分配好的內存對象 ,最好采用 [class alloc]init 這種二段式寫法,不然可能會有未知的問題,巧神說的
- (void)dealloc
MRC時代很重要,用于類銷毀的時候釋放,清空一些變量,ARC時代基本不用重寫,除了一些計時器的銷毀或者通知的移除等等。
- (void)finalize
一些垃圾回收的事,一般不主動調用
** - (id)copy**
不可變的拷貝,需要實現copyWithZone
- (id)mutableCopy
可變的拷貝
@property (copy) NSMutableArray *array 或
NSMutableArray *array = [array copy]是錯誤的 ,經過copy,array變成了不可變的,后續操作會引發crash**- (IMP)methodForSelector:(SEL)aSelector **
+ (IMP)instanceMethodForSelector:(SEL)aSelector獲取aSelector方法指針,用法:頻繁調用某個方法,可以利用這自己組裝成方法,提高性能
- (void)doesNotRecognizeSelector:(SEL)aSelector
手動制造crash。用法:父類提供純虛函數,比如A中有個方法
- (void)show
{
// Subclasses need to override this method...
[self doesNotRecognizeSelector:_cmd];
}
那么繼承A的子類,想要實現show方法,必須重寫,直接調用的話crash。** - (BOOL)allowsWeakReference **
** - (BOOL)retainWeakReference**OC中有一些類,并不支持ARC,例如NSMachPort類。可以通過此方法來判斷是否支持ARC
+ (BOOL)isSubclassOfClass:(Class)aClass
類方法:判斷是否是某個類或其子類,作用于isKindOfClass一致。
有關消息轉發
unrecognized selector sent to instance,這種錯誤應該不少見,調用了類不存在的方法導致Crash,在崩潰前我們有三次機會挽救一下
1.自救(動態增加方法)
- (BOOL)resolveInstanceMethod:(SEL)sel
2.轉發其他類
- (id)forwardingTargetForSelector:(SEL)aSelector
3.形成簽名然后轉發
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
- (void)forwardInvocation:(NSInvocation *)anInvocation
詳情見Demo