利用runtime來實現(xiàn)一個數(shù)組防崩潰替換

前言

很多時候,我們常常在使用數(shù)組的時候因為數(shù)組越界而導(dǎo)致程序崩潰。我們通過runtime中的特殊手段,實現(xiàn)在運行時互換函數(shù),達到偷天換日效果。

Method Swizzling

Method Swizzling是發(fā)生在運行時期的,主要是在運行時,將兩個Method交換。達到偷天換日的效果,Method Swizzling是面向切面編程的一種技術(shù)。

OBJC_EXPORT void method_exchangeImplementations(Method m1, Method m2) 
 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
#import <Foundation/Foundation.h>
/**
 *  不可變數(shù)組防越界崩潰處理
 */
@interface NSArray (AXKArray)

@end
#import "NSArray+AXKArray.h"
#import <objc/runtime.h>

@implementation NSArray (AXKArray)

+ (void)load
{
    [super load];
    Method originalMethod = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtIndex:));
    Method userMethod = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(axk_objectAtIndex:));
    if (!class_addMethod(objc_getClass("__NSArrayI"), @selector(objectAtIndex:), method_getImplementation(userMethod), method_getTypeEncoding(userMethod))) {
         method_exchangeImplementations(originalMethod, userMethod);
    }
}
- (id)axk_objectAtIndex:(NSUInteger)index
{
    if (self.count - 1 < index) {
        //異常處理,捕獲異常并拋出異
        @try {
            return [self axk_objectAtIndex:index];
        }
        @catch (NSException *exception) {
            NSLog(@"不可變數(shù)組越界訪問異常--%s--Crash Because Method--%s---以上異常", class_getName(self.class), __func__);
            NSLog(@"異常下標(biāo)--%lu--", index);
            NSLog(@"不可變數(shù)組越界訪問異常日志%@", [exception callStackSymbols]);
            return nil;
        }
        @finally {
            
        }
    } else {
        return [self axk_objectAtIndex:index];
    }
}
@end

類簇、替身、真身

在iOS中存在大量的有關(guān)類簇、真身、替身相關(guān)的類等

大家發(fā)現(xiàn)了嗎,__NSArrayI才是NSArray真正的類,而NSMutableArray又不一樣。我們可以通過runtime函數(shù)獲取真正的類:

objc_getClass("__NSArrayI")
下面我們列舉一些常用的類簇的“真身”:

真身
NSArray __NSArrayI
NSMutableArray __NSArrayM
NSDictionary __NSDictionaryI
NSMutableDictionary __NSDictionaryM

Method Swizzling方法只能對替身的真身有效,對替身沒有效果。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容