關(guān)于分類在開發(fā)中我們都經(jīng)常常見,category在加上runtime能實現(xiàn)好多意想不到的效果谴轮,最近在學(xué)習(xí)中突然了解到category可以省下好多代碼末购。這對于是小白的我感覺 像打開了新天地殴胧。
最近在閱讀博客的時候,發(fā)現(xiàn)一篇文章挑宠,如何判斷數(shù)組越界的情況,如果一行一行的判斷寫颓影,不近費事費時各淀,還不一定所有的都能判斷到,但是如果在編譯的時候就替換系統(tǒng)的方法诡挂,這樣我們就不用逐個判斷了碎浇。
在說分類之前需要先了解一些load 和 initialize的區(qū)別
load:是在main函數(shù)調(diào)用之前就已經(jīng)加載的方法
initialize:是在main函數(shù)之后init方法之前加載的方法,主要進(jìn)行一些初始化的操作
此外還想在多說兩句璃俗,load加載類的時候奴璃,加載的順序是類,子類城豁,分類苟穆,注意如果有好多分類的時候,加載的順序是根據(jù)編譯的書序來判斷的唱星。有興趣的朋友可以詳細(xì)看一下分類雳旅。
而調(diào)用的時候順序正好相反,分類间聊,子類岭辣,類。分類如果實現(xiàn)了父類的方法甸饱,則會覆蓋掉父類的方法沦童。而load方法不會覆蓋。
下面進(jìn)入正題叹话,話不多說直接上代碼
+ (void)load{
? ? //替換objectAtIndex方法
? ? MethodfromMethod =class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(objectAtIndex:));
? ? MethodtoMethod =class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(wb_objectAtIndex:));
? ? method_exchangeImplementations(fromMethod, toMethod);
? ? //替換array【0】獲取元素的方法
? ? MethodfromMethod1 =class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(objectAtIndexedSubscript:));
? ? MethodtoMethod1 =class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(wb_objectAtIndexedSubscript:));
? ? method_exchangeImplementations(fromMethod1, toMethod1);
? ? //替換objectAtIndex方法
? ? MethodmfromMethod =class_getInstanceMethod(objc_getClass("__NSArrayM"),@selector(objectAtIndex:));
? ? MethodmtoMethod =class_getInstanceMethod(objc_getClass("__NSArrayM"),@selector(wb_mobjectAtIndex:));
? ? method_exchangeImplementations(mfromMethod, mtoMethod);
? ? //替換array【0】獲取元素的方法
? ? MethodmfromMethod1 =class_getInstanceMethod(objc_getClass("__NSArrayM"),@selector(objectAtIndexedSubscript:));
? ? MethodmtoMethod1 =class_getInstanceMethod(objc_getClass("__NSArrayM"),@selector(wb_mobjectAtIndexedSubscript:));
? ? method_exchangeImplementations(mfromMethod1, mtoMethod1);
}
-(id)wb_objectAtIndexedSubscript:(NSUInteger)index{
? ? if(self.count-1< index|| !self.count) {
? ? ? ? @try{
? ? ? ? ? ? return [self wb_objectAtIndexedSubscript:index];
? ? ? ? }@catch(NSException *exception) {
? ? ? ? ? ? // 在崩潰后會打印崩潰信息偷遗。如果是線上,可以在這里將崩潰信息發(fā)送到服務(wù)器
? ? ? ? ? ? NSLog(@"---------- %s Crash Because Method %s? ----------\n", class_getName(self.class), __func__);
? ? ? ? ? ? NSLog(@"%@",[exceptioncallStackSymbols]);
? ? ? ? ? ? returnnil;
? ? ? ? }@finally{
? ? ? ? }
? ? }else{
? ? ? ? return [self wb_objectAtIndexedSubscript:index];
? ? }
}
-(id)wb_objectAtIndex:(NSUInteger)index{
? ? if(self.count-1< index|| !self.count) {
? ? ? ? @try{
? ? ? ? ? ? return[selfwb_objectAtIndex:index];
? ? ? ? }@catch(NSException *exception) {
? ? ? ? ? ? // 在崩潰后會打印崩潰信息驼壶。如果是線上氏豌,可以在這里將崩潰信息發(fā)送到服務(wù)器
? ? ? ? ? ? NSLog(@"---------- %s Crash Because Method %s? ----------\n", class_getName(self.class), __func__);
? ? ? ? ? ? NSLog(@"%@",[exceptioncallStackSymbols]);
? ? ? ? ? ? returnnil;
? ? ? ? }@finally{
? ? ? ? }
? ? }else{
? ? ? ? return[selfwb_objectAtIndex:index];
? ? }
}
-(id)wb_mobjectAtIndexedSubscript:(NSUInteger)index{
? ? if(self.count-1< index) {
? ? ? ? @try{
? ? ? ? ? ? return [self wb_mobjectAtIndexedSubscript:index];
? ? ? ? }@catch(NSException *exception) {
? ? ? ? ? ? // 在崩潰后會打印崩潰信息。如果是線上热凹,可以在這里將崩潰信息發(fā)送到服務(wù)器
? ? ? ? ? ? NSLog(@"---------- %s Crash Because Method %s? ----------\n", class_getName(self.class), __func__);
? ? ? ? ? ? NSLog(@"%@",[exceptioncallStackSymbols]);
? ? ? ? ? ? returnnil;
? ? ? ? }@finally{
? ? ? ? }
? ? }else{
? ? ? ? return [self wb_mobjectAtIndexedSubscript:index];
? ? }
想深入了解的可以看一下這偏如果讓分類不覆蓋類方法:http://www.reibang.com/p/81291aceceb2