iOS-Crash防護(hù)方案整理

iOS - Crash防護(hù)主要有以下幾個方面
1,子線程訪問UI:通過runtime攔截幾個UI方法,并且監(jiān)聽當(dāng)前線程,如果不是主線程則強(qiáng)行轉(zhuǎn)回主線程,并且可以進(jìn)行上報

[objc_getClass("UIView") swizzleMethod:@selector(setNeedsLayout) swizzledSelector:@selector(replace_setNeedsLayout)];

[objc_getClass("UIView") swizzleMethod:@selector(setNeedsDisplay) swizzledSelector:@selector(replace_setNeedsDisplay)];
-(void)replace_setNeedsLayout{
    if ([NSThread isMainThread]) {
        return [self replace_setNeedsLayout];
    }else{
        dispatch_async(dispatch_get_main_queue(), ^{
            return [self replace_setNeedsLayout];
        });
    }
}

-(void)replace_setNeedsDisplay{
    if ([NSThread isMainThread]) {
        return [self replace_setNeedsDisplay];
    }else{
        dispatch_async(dispatch_get_main_queue(), ^{
            return [self replace_setNeedsDisplay];
        });
    }
}

2,調(diào)用不存在函數(shù)(hook:forwardingTargetForSelector,把方法轉(zhuǎn)到一個自定義對象,并在改對象添加該不存在方法

[objc_getClass("NSObject") swizzleMethod:@selector(forwardingTargetForSelector:) swizzledSelector:@selector(replace_forwardingTargetForSelector:)];

- (id)replace_forwardingTargetForSelector:(SEL)aSelector
{
    NSMethodSignature *signature = [self methodSignatureForSelector:aSelector];
    if ([self respondsToSelector:aSelector] || signature) {
        return [self replace_forwardingTargetForSelector:aSelector];
    }
    
    return [NSObject createFakeForwardTargetObject:self selector:aSelector];

}

+ (id)createFakeForwardTargetObject:(id)aTarget selector:(SEL)aSelector
{
    if ([[NSString string] respondsToSelector:aSelector]) {
        NSString *szTarget = nil;
        if ([aTarget isKindOfClass:[NSNumber class]]) {
            szTarget = [NSString stringWithFormat:@"%@", aTarget];
        }
        
        if (szTarget) {
            return szTarget;
        }
    }

    FakeForwardTargetObject *fakeTaget = [[FakeForwardTargetObject alloc] initWithSelector:aSelector];
    return fakeTaget;
}

3,KVO重復(fù)添加監(jiān)聽回調(diào)去重功能,KVO重復(fù)remove導(dǎo)致crash問題.方案:runtime攔截,添加移除Api,通過KVC拿到私有api,進(jìn)行判斷去重

[objc_getClass("NSObject") swizzleMethod:@selector(removeObserver:forKeyPath:) swizzledSelector:@selector(removeDasen:forKeyPath:)];
            [objc_getClass("NSObject") swizzleMethod:@selector(addObserver:forKeyPath:options:context:) swizzledSelector:@selector(addDasen:forKeyPath:options:context:)];

// 交換后的方法
- (void)removeDasen:(NSObject *)observer forKeyPath:(NSString *)keyPath
{
    if ([self observerKeyPath:keyPath observer:observer]) {
        [self removeDasen:observer forKeyPath:keyPath];
    }
}


// 交換后的方法
- (void)addDasen:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
{
    
    objc_setAssociatedObject(self, "addObserverFlag", @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    if (![self observerKeyPath:keyPath observer:observer]) {
        [self addDasen:observer forKeyPath:keyPath options:options context:context];
    }
}


// 進(jìn)行檢索獲取Key
- (BOOL)observerKeyPath:(NSString *)key observer:(id )observer
{
    id info = self.observationInfo;
    NSArray *array = [info valueForKey:@"_observances"];
    for (id objc in array) {
        id Properties = [objc valueForKeyPath:@"_property"];
        id newObserver = [objc valueForKeyPath:@"_observer"];
        
        NSString *keyPath = [Properties valueForKeyPath:@"_keyPath"];
        if ([key isEqualToString:keyPath] && [newObserver isEqual:observer]) {
            return YES;
        }
    }
    return NO;
}

4,iOS9.0系統(tǒng)以上監(jiān)聽對象dealloc,沒有移除通知導(dǎo)致崩潰問題.方案:通過runtimehook添加和deallocApi,進(jìn)行移除操作

[objc_getClass("NSNotificationCenter") swizzleMethod:@selector(addObserver:selector:name:object:) swizzledSelector:@selector(ghl_addObserver:selector:name:object:)];

            [objc_getClass("NSObject") swizzleMethod:NSSelectorFromString(@"dealloc") swizzledSelector:@selector(replaceDealloc)];


- (void)replaceDealloc
{
    NSString *addObserver = objc_getAssociatedObject(self, "addObserverFlag");
    if ([addObserver boolValue]) {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    [self replaceDealloc];
}
- (void)ghl_addObserver:(id)observer selector:(SEL)aSelector name:(NSNotificationName)aName object:(id)anObject {
    [self ghl_addObserver:observer selector:aSelector name:aName object:anObject];
    
    objc_setAssociatedObject(observer, "addObserverFlag", @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}


5,容器類問題:oc數(shù)組越界,字符串操作越界,UITableView和UICollectionView操作數(shù)據(jù)越界問題.具體查看demo.這里可以提一句,類似NSArray這種類是一種類簇,類似一種多態(tài)的操作,內(nèi)部根據(jù)某些情況會調(diào)用具體的類

demo:https://github.com/riceForChina/SafeTool.git
參考文章:https://neyoufan.github.io/2017/01/13/ios/BayMax_HTSafetyGuard/#kvo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奖地,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子坛悉,更是在濱河造成了極大的恐慌,老刑警劉巖乒省,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件相恃,死亡現(xiàn)場離奇詭異,居然都是意外死亡距淫,警方通過查閱死者的電腦和手機(jī)绞绒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榕暇,“玉大人蓬衡,你說我怎么就攤上這事⊥啵” “怎么了狰晚?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長缴啡。 經(jīng)常有香客問我壁晒,道長,這世上最難降的妖魔是什么业栅? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任秒咐,我火速辦了婚禮,結(jié)果婚禮上碘裕,老公的妹妹穿的比我還像新娘携取。我一直安慰自己,他們只是感情好帮孔,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布雷滋。 她就那樣靜靜地躺著,像睡著了一般文兢。 火紅的嫁衣襯著肌膚如雪晤斩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天禽作,我揣著相機(jī)與錄音尸昧,去河邊找鬼。 笑死旷偿,一個胖子當(dāng)著我的面吹牛烹俗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播萍程,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼幢妄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了茫负?” 一聲冷哼從身側(cè)響起蕉鸳,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后潮尝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體榕吼,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年勉失,在試婚紗的時候發(fā)現(xiàn)自己被綠了羹蚣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡乱凿,死狀恐怖顽素,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情徒蟆,我是刑警寧澤胁出,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站段审,受9級特大地震影響全蝶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寺枉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一裸诽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧型凳,春花似錦、人聲如沸嘱函。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽往弓。三九已至疏唾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間函似,已是汗流浹背槐脏。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撇寞,地道東北人顿天。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像蔑担,于是被迫代替她去往敵國和親牌废。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評論 2 350

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