深刻淺出 Runtime(一):初識
深刻淺出 Runtime(二):數據結構
深刻淺出 Runtime(三):消息機制
深刻淺出 Runtime(四):super 的本質
深刻淺出 Runtime(五):具體應用
深刻淺出 Runtime(六):相關面試題git
C、彙編
編寫的運行時庫,包含了不少 C 語言的 API,封裝了不少動態性相關的函數;OC
的動態性就是由 Runtime
來支撐和實現的,Rumtime
就是它的核心;OC
代碼,底層都是轉換成了 Runtime API
進行調用。unrecognized selector send to instance/class
。對於 NSString *string = [[NSMutableArray alloc]init]
;github
NSString
類型的指針賦值的是一個NSMutableArray
對象,因此編譯器會給出類型不匹配的警告。可是編譯器會將 string
看成NSString
的實例,因此string
對象調用NSString
的方法,編譯沒有任何問題,而調用NSMutableArray
的方法,編譯會直接報錯。string
其實是指向一個NSMutableArray
對象,NSMutableArray
對象沒有stringByAppendingString:
方法,因此致使crash:unrecognized selector send to instance
。NSString *string = [[NSMutableArray alloc]init]; //⚠️Incompatible pointer types initializing 'NSString *' with an expression of type 'NSMutableArray *'
[string stringByAppendingString:@"abc"];
[string addObject:@"abc"]; //❌No visible @interface For 'NSString' declares the selector 'addObject:'
複製代碼
32-bit programs on OS X desktop
;iPhone applications and 64-bit programs on OS X v10.5 and later
。// 根據 instance 對象或者類名得到一個 class 對象
- (Class)class
+ (Class)class
// 判斷當前 instance/class 對象的 isa 指向是否是 class/meta-class 對象或者它的子類類型
- (BOOL)isKindOfClass:(Class)cls
+ (BOOL)isKindOfClass:(Class)cls
// 判斷當前 instance/class 對象的 isa 指向是否是 class/meta-class 對象類型
- (BOOL)isMemberOfClass:(Class)cls
+ (BOOL)isMemberOfClass:(Class)cls
// 判斷對象是否能夠接收特定消息
- (BOOL)respondsToSelector:(SEL)sel
+ (BOOL)respondsToSelector:(SEL)sel
// 判斷對象是否實現了特定協議中定義的方法
- (BOOL)conformsToProtocol:(Protocol *)protocol
+ (BOOL)conformsToProtocol:(Protocol *)protocol
// 能夠根據一個 SEL,獲得該方法的 IMP
- (IMP)methodForSelector:(SEL)sel
+ (IMP)methodForSelector:(SEL)sel
複製代碼
類相關面試
// 動態建立一對類和元類(參數:父類,類名,額外的內存空間)
Class objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes)
// 註冊一對類和元類(要在類註冊以前添加成員變量)
void objc_registerClassPair(Class cls)
// 銷燬一對類和元類
void objc_disposeClassPair(Class cls)
// 獲取 isa 指向的 Class
Class object_getClass(id obj)
// 設置 isa 指向的 Class
Class object_setClass(id obj, Class cls)
// 判斷一個 OC 對象是否爲 Class
BOOL object_isClass(id obj)
// 判斷一個 Class 是否爲元類
BOOL class_isMetaClass(Class cls)
// 獲取父類
Class class_getSuperclass(Class cls)
複製代碼
成員變量相關objective-c
// 獲取一個實例變量信息
Ivar class_getInstanceVariable(Class cls, const char *name)
// 拷貝實例變量列表(最後須要調用 free 釋放)
Ivar *class_copyIvarList(Class cls, unsigned int *outCount)
// 設置和獲取成員變量的值
void object_setIvar(id obj, Ivar ivar, id value)
id object_getIvar(id obj, Ivar ivar)
// 動態添加成員變量(已經註冊的類是不能動態添加成員變量的)
BOOL class_addIvar(Class cls, const char * name, size_t size, uint8_t alignment, const char * types)
// 獲取成員變量的相關信息
const char *ivar_getName(Ivar v)
const char *ivar_getTypeEncoding(Ivar v)
複製代碼
屬性相關express
// 獲取一個屬性
objc_property_t class_getProperty(Class cls, const char *name)
// 拷貝屬性列表(最後須要調用 free 釋放)
objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
// 動態添加屬性
BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
// 動態替換屬性
void class_replaceProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
// 獲取屬性的一些信息
const char *property_getName(objc_property_t property)
const char *property_getAttributes(objc_property_t property)
複製代碼
方法相關編程
// 得到一個實例方法、類方法
Method class_getInstanceMethod(Class cls, SEL name)
Method class_getClassMethod(Class cls, SEL name)
// 方法實現相關操做
IMP class_getMethodImplementation(Class cls, SEL name)
IMP method_setImplementation(Method m, IMP imp)
void method_exchangeImplementations(Method m1, Method m2)
// 拷貝方法列表(最後須要調用 free 釋放)
Method *class_copyMethodList(Class cls, unsigned int *outCount)
// 動態添加方法
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
// 動態替換方法
IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)
// 獲取方法的相關信息(帶有 copy 的須要調用 free 去釋放)
SEL method_getName(Method m)
IMP method_getImplementation(Method m)
const char *method_getTypeEncoding(Method m)
unsigned int method_getNumberOfArguments(Method m)
char *method_copyReturnType(Method m)
char *method_copyArgumentType(Method m, unsigned int index)
// 選擇器相關
const char *sel_getName(SEL sel)
SEL sel_registerName(const char *str)
// 用 block 做爲方法實現
IMP imp_implementationWithBlock(id block)
id imp_getBlock(IMP anImp)
BOOL imp_removeBlock(IMP anImp)
複製代碼
關聯對象相關數據結構
// 添加關聯對象
void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)
// 得到關聯對象
id objc_getAssociatedObject(id object, const void * key)
// 移除指定 object 的全部關聯對象
void objc_removeAssociatedObjects(id object)
複製代碼