ios開發Runtime的簡單使用方法,ios開發runtime
ios開發Runtime的簡單使用方法,其實在OC底層本質上就是C語言函數的調用,去動態發送訊息。下面就拿一個alloc init的方法來舉個例子,我們完全可以去調用運行時的函數,這樣就可以去建立一個對象了。
Person * p = objc_msgSend(objc_getClass("Person"),sel_registerName("alloc")); objc_msgSend(p, sel_registerName("init"));
其實我們在終端也可以去輸入下面的命令,就可以去查看OC的C語言的實現,就會發現其實建立對象就和上面的運行時代碼是很像的
clang -rewrite-objc main.m
在這裡也需要瞭解兩個概念性的問題就是SEL和IMP,其實SEL就是方法的編號,而IMP就是需要去執行方法的指標,我們可以通過方法的編號去找到這個代碼的具體實現。
我們在下面可以進行交換兩個對象的方法,其中Method就是指向struct objc_method的指標。其實SEL和IMP就相當於是一本書裡面的標題和頁碼,我們可以通過標題知道頁碼,當然也可以去根據頁碼知道具體的內容。
Method method1 = class_getInstanceMethod([self class], @selector(eat)); Method method2 = class_getInstanceMethod([self class], @selector(sleep)); //進行方法交換 method_exchangeImplementations(method1, method2);
有兩個方法是我們需要知道的一個就是當我們沒有實現某個我們調用的類方法的時候回來到下面的這個函數
+(BOOL)resolveClassMethod:(SEL)sel
另外一個就是在我們實現我們調用的對象方法的時候如果沒找到會調用下面的這個函數
+(BOOL)resolveInstanceMethod:(SEL)sel
如果我們想要在運行時動態添加函數就可以在這裡面進行添加,並且下面需要注意的是如果我們要寫的函數要帶有參數的話,那麼函數的前面就要帶有兩個參數,一個是self,還有一個就是SEL _cmd,當前_cmd你可以改名字。self其實就是方法的調用者,而SEL其實就是方法的編號
+(BOOL)resolveInstanceMethod:(SEL)sel{ //動態添加方法 /*方法的參數一:是這個類 參數二:方法 參數三 函數指標 參數四 就是傳回值的類型加參數 */ class_addMethod(self, sel,hello,""); return [super resolveInstanceMethod:sel];}void hello(id self,SEL _cmd,NSString *str1,NSString * str2){ NSLog(@"%@------%@",str1,str2); NSLog(@"hello world");}
還有一個需要注意的是死迴圈可能不會導致程式直接崩潰,但是如果是函數的遞迴調用就肯定會導致程式的崩潰的,因為函數執行的時候有自己的臨時棧,所以會導致堆疊溢位了,導致程式崩潰。