AXKit icon indicating copy to clipboard operation
AXKit copied to clipboard

让代码具有冷却时间

Open xaoxuu opened this issue 7 years ago • 0 comments

必要性

首先我个人认为设计合理、逻辑严谨的代码是用不到这个机制的,但是我们不能保证我们面对的代码永远都是完美的,所以我就提供了这个冷却机制以延长那些癌症晚期的代码的寿命。

优点:执行代码像放技能一样,可以强行打破死循环、避免死循环、避免过高频率访问某一资源、从一定程度上缓解了内存、CPU压力。

缺点:治标不治本,最好是找出会产生问题的代码,从根源上解决问题。

使用示例

示例1

某种耗时耗能操作,希望在某种条件下触发,但又担心用户频繁触发,就可以这样:

// @xaoxuu: 重新获取数据源并刷新tableView
- (void)reloadDataAndRefreshTableView{
    // 无论如何,2秒内最多只会执行一次此方法。
    [NSBlockOperation ax_delay:0 cooldown:2 token:@"reload data and refresh table view" performInMainQueue:^{
        [self.dataList removeAllObjects];
        [self reloadTableView];
    }];
}
- (IBAction)btn1:(UIButton *)sender {
    [NSBlockOperation ax_delay:0 cooldown:60 token:self performInMainQueue:^{
        // @xaoxuu: 立即在主线程施放大招,冷却时间是60秒。
    }];
}

- (IBAction)btn2:(UIButton *)sender {
    [NSBlockOperation ax_delay:2 cooldown:120 token:self performInBackground:^{
        // @xaoxuu: 延迟2秒后在后台默默施放大招,冷却时间是120秒。
    }];
}
// @xaoxuu: 两者的token相同则共享冷却时间。

示例2

如何强行打破死循环?说实话我是没有遇到这种需求,仅仅是这个机制有这种能力,觉得挺有趣,就尝试一下:

// 自己调用自己,无限循环
- (void)loop{
    AXLogFunc();
    [self loop];
}
// 自己调用自己,但是发现代码在冷却,所以就失效了,一个环节被中断,死循环就被打破了
- (void)loop{
    AXLogFunc();
    [NSBlockOperation ax_delay:0 cooldown:0.0001 token:@"loop" performInMainQueue:^{
        [self loop];
    }];
}

实现原理

给每一个block分配一个dispatch_after的函数,执行的时候开始计时,并且函数标记为disable,计时结束后重新enable。

xaoxuu avatar May 07 '17 12:05 xaoxuu