runtime解決button多次點擊響應網(wǎng)絡請求

UIButton在開發(fā)中經(jīng)常遇到的兩個問題弦撩,

1步咪、 第一個問題是多個button可以同時響應。
2益楼、 第二問題點擊button發(fā)送網(wǎng)絡請求時(特別是請求后要跳轉)猾漫, 就算有HUD, 但全局封裝的HUD有時候也不給力感凤, 會發(fā)生多次響應多次跳轉的問題悯周。

第一個問題解決:
最好在自定義基類button的初始化方法里面添加

- (instancetype)initWithCoder:(NSCoder *)coder
  {
self = [super initWithCoder:coder];
if (self) {
   //self.cg_Intervals = 1.5;
    [self setExclusiveTouch:YES];
}
return self;
}

- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
    //self.cg_Intervals = 1.5;
    [self setExclusiveTouch:YES];
}
return self;
}

第二個問題要么可以用延遲響應(代碼如下),但用戶體驗不好.

   [self performSelector:<#(nonnull SEL)#> withObject:<#(nullable id)#> afterDelay:<#(NSTimeInterval)#>];
最終解決方法陪竿,用runtime黑魔法禽翼,給button創(chuàng)建category, 添加屬性cg_Intervals(響應間隔時長)族跛、cg_lastOKTime(上一次響應時間)闰挡, 并替換button原有的方法。代碼如下:

.h代碼:

#import <UIKit/UIKit.h>
@interface UIButton (Delay)
/// 間隔時間
@property (nonatomic, assign) NSTimeInterval cg_Intervals;
/// 上一次允許點擊的時間
@property(nonatomic, assign) NSTimeInterval cg_lastOKTime;
@end

.m代碼:

#import "UIButton+Delay.h"
#import <objc/runtime.h>

@implementation UIButton (Delay)
static const char * UIControl_Intervals = "UIControl_Intervals";
static const char * UIControl_lastOKTime =     "UIControl_lastOKTime";


-(void)setCg_Intervals:(NSTimeInterval)cg_Intervals{
objc_setAssociatedObject(self, UIControl_Intervals, @(cg_Intervals), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
  - (NSTimeInterval)cg_Intervals{
return [objc_getAssociatedObject(self, UIControl_Intervals) doubleValue];
    }

- (NSTimeInterval)cg_lastOKTime{
return [objc_getAssociatedObject(self, UIControl_lastOKTime) doubleValue];
}


- (void)setCg_lastOKTime:(NSTimeInterval)cg_lastOKTime{
objc_setAssociatedObject(self, UIControl_lastOKTime, @(cg_lastOKTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

  +(void)load{

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    Class class = [self class];
    //分別獲取
    SEL beforeSelector = @selector(sendAction:to:forEvent:);
    SEL afterSelector = @selector(cg_sendAction:to:forEvent:);
    
    Method beforeMethod = class_getInstanceMethod(class, beforeSelector);
    Method afterMethod = class_getInstanceMethod(class, afterSelector);
    //先嘗試給原來的方法添加實現(xiàn)庸蔼,如果原來的方法不存在就可以添加成功解总。返回為YES,否則
    //返回為NO姐仅。
    //UIButton 真的沒有sendAction方法的實現(xiàn)花枫,這是繼承了UIControl的而已,UIControl才真正的實現(xiàn)了掏膏。
    BOOL didAddMethod =
    class_addMethod(class,
                    beforeSelector,
                    method_getImplementation(afterMethod),
                    method_getTypeEncoding(afterMethod));
   // NSLog(@"%d",didAddMethod);
    if (didAddMethod) {
        // 如果之前不存在劳翰,但是添加成功了,此時添加成功的是cs_sendAction方法的實現(xiàn)
        // 這里只需要方法替換
        class_replaceMethod(class,
                            afterSelector,
                            method_getImplementation(beforeMethod),
                            method_getTypeEncoding(beforeMethod));
    } else {
        //本來如果存在就進行交換
        method_exchangeImplementations(afterMethod, beforeMethod);
    }
});

}


- (void)cg_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{
    /// 兩次點擊時差小于間隔的時候不響應
    if((double)[NSDate date].timeIntervalSince1970 - (double)self.cg_lastOKTime < self.cg_Intervals)
        return;
    if(self.cg_Intervals > 0){// 設置了間隔
        self.cg_lastOKTime = [NSDate date].timeIntervalSince1970;
    }
[self cg_sendAction:action to:target forEvent:event];

}
本案例成功應用了runtime的關聯(lián)對象馒疹、method swizzling成功解決了問題佳簸, runtime的應用遠不止如此, 原理有消息傳遞颖变、消息轉發(fā)等生均。應用還有歸檔解檔、字典轉模型等等腥刹。马胧。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市衔峰,隨后出現(xiàn)的幾起案子佩脊,更是在濱河造成了極大的恐慌蛙粘,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件威彰,死亡現(xiàn)場離奇詭異出牧,居然都是意外死亡,警方通過查閱死者的電腦和手機歇盼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門舔痕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人豹缀,你說我怎么就攤上這事赵讯。” “怎么了耿眉?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鱼响。 經(jīng)常有香客問我鸣剪,道長,這世上最難降的妖魔是什么丈积? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任筐骇,我火速辦了婚禮,結果婚禮上江滨,老公的妹妹穿的比我還像新娘铛纬。我一直安慰自己,他們只是感情好唬滑,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布告唆。 她就那樣靜靜地躺著,像睡著了一般晶密。 火紅的嫁衣襯著肌膚如雪擒悬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天稻艰,我揣著相機與錄音懂牧,去河邊找鬼。 笑死尊勿,一個胖子當著我的面吹牛僧凤,可吹牛的內容都是我干的。 我是一名探鬼主播元扔,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼躯保,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了摇展?” 一聲冷哼從身側響起吻氧,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤溺忧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后盯孙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲁森,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年振惰,在試婚紗的時候發(fā)現(xiàn)自己被綠了歌溉。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡骑晶,死狀恐怖痛垛,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情桶蛔,我是刑警寧澤匙头,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站仔雷,受9級特大地震影響蹂析,放射性物質發(fā)生泄漏。R本人自食惡果不足惜碟婆,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一电抚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧竖共,春花似錦蝙叛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至淌铐,卻和暖如春姻蚓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背匣沼。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工狰挡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人释涛。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓加叁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親唇撬。 傳聞我的和親對象是個殘疾皇子它匕,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內容