iOS卡頓 防止多次PUSH一個頁面

iOS卡頓這個問題本身就是個問題数焊,但有這個問題避免不了萬一卡了呢挂捅。

在網(wǎng)絡(luò)少著了很多資料都感覺有些問題,下面是我根據(jù)網(wǎng)絡(luò)上的方案改良一下;

問題描述:
當(dāng)PUSH一個新的ViewController的時候状土,不管是init的過于臃腫還是耗時操作沒有處理无蜂,都有可能導(dǎo)致卡頓;
暴力的測試喜歡狂點蒙谓,這就出現(xiàn)了同一個ViewController被PUSH了多次

我通過重寫導(dǎo)航控制器的方法來解決這個問題斥季。

#import <UIKit/UIKit.h>  
  
@interface YBRNaviViewController : UINavigationController  
  
@end  
#import "YBRNavigationController.h"
#import "Aspects.h" //一個可以Hook方法的庫

@interface YBRNavigationController ()
<
UINavigationControllerDelegate
>
{
    BOOL _pushing;
    id<Aspect> _aspect;
}

@end

@implementation YBRNavigationController

- (instancetype)initWithRootViewController:(UIViewController *)rootViewController
{
    self = [super initWithRootViewController:rootViewController];
    if (self) {
        self.delegate = self; //默認(rèn)代理設(shè)置Self
    }
    return self;
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {

    //這個地方有個問題,initWithRootViewController會觸發(fā)pushViewController
    if (self.viewControllers.count == 0) {
        [super pushViewController:viewController animated:animated];
        return;
    }
    
    if (_pushing == YES) {
        NSLog(@"被攔截 %@",viewController);
        return;
    }else {
        NSLog(@"PUSH %@",viewController);
        _pushing = YES;
    }
   [super pushViewController:viewController animated:animated];
}

- (void)setDelegate:(id<UINavigationControllerDelegate>)delegate {
    [super setDelegate:delegate];

    //移除_aspect
    if (_aspect) {
        [_aspect remove];
    }
    
    if (delegate && ![self isEqual:delegate]) {
        //不是Self
        if ([delegate respondsToSelector:@selector(navigationController:didShowViewController:animated:)]) {
            //當(dāng)delegate已經(jīng)實現(xiàn) navigationController:didShowViewController:animated: 的時候累驮,
            //Hook 該方法
            //當(dāng)然也可以使用 swizzleMethod 酣倾,Aspect的API更友好些
            __weak __typeof(self)weakSelf = self;
            _aspect = [((NSObject *)delegate) aspect_hookSelector:@selector(navigationController:didShowViewController:animated:) withOptions:AspectPositionAfter usingBlock:^(id instance, NSArray *args) {
                [weakSelf navigationController:args[0] didShowViewController:args[1] animated:args[2]];
            } error:nil];
        }else {
            //為delegate動態(tài)添加 navigationController:didShowViewController:animated:
            //不知道有沒有這方面的庫可以用,只能自己寫
            Class class = [delegate class];
            
            swizzleMethod(class, @selector(navigationController:didShowViewController:animated:), @selector(navigationController:didShowViewController:animated:));
        }
    }
}

#pragma mark - UINavigationControllerDelegate
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    _pushing = NO; //完成PUSH
}

@end

///黑魔法
void swizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector)
{
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    
    BOOL didAddMethod =
    class_addMethod(class,
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));
    
    if (didAddMethod) {
        class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谤专,一起剝皮案震驚了整個濱河市躁锡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌毒租,老刑警劉巖稚铣,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異墅垮,居然都是意外死亡惕医,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門算色,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抬伺,“玉大人,你說我怎么就攤上這事灾梦∠康觯” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵若河,是天一觀的道長能岩。 經(jīng)常有香客問我,道長萧福,這世上最難降的妖魔是什么拉鹃? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮鲫忍,結(jié)果婚禮上膏燕,老公的妹妹穿的比我還像新娘。我一直安慰自己悟民,他們只是感情好坝辫,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著射亏,像睡著了一般近忙。 火紅的嫁衣襯著肌膚如雪竭业。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天银锻,我揣著相機與錄音永品,去河邊找鬼。 笑死击纬,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的钾麸。 我是一名探鬼主播更振,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼饭尝!你這毒婦竟也來了肯腕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤钥平,失蹤者是張志新(化名)和其女友劉穎实撒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涉瘾,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡知态,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了立叛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片负敏。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖秘蛇,靈堂內(nèi)的尸體忽然破棺而出其做,到底是詐尸還是另有隱情,我是刑警寧澤赁还,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布妖泄,位于F島的核電站,受9級特大地震影響艘策,放射性物質(zhì)發(fā)生泄漏蹈胡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一柬焕、第九天 我趴在偏房一處隱蔽的房頂上張望审残。 院中可真熱鬧,春花似錦斑举、人聲如沸搅轿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽璧坟。三九已至既穆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雀鹃,已是汗流浹背幻工。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留黎茎,地道東北人囊颅。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像傅瞻,于是被迫代替她去往敵國和親踢代。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

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