Ios 随机非时不变维

Ios 随机非时不变维,ios,objective-c,nstimer,Ios,Objective C,Nstimer,因此,要启动NSTimer,我们需要执行以下操作: timer = [NSTimer scheduledTimerWithTimeInterval:0.35 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES]; 但是如果我想让它每0.3-0.7秒(随机)运行一次呢。我不能做arc4random,因为这样它会选择一个数字并坚持它 timer = [NSTimer scheduledTimerWithTimeI

因此,要启动
NSTimer
,我们需要执行以下操作:

timer = [NSTimer scheduledTimerWithTimeInterval:0.35 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
但是如果我想让它每0.3-0.7秒(随机)运行一次呢。我不能做
arc4random
,因为这样它会选择一个数字并坚持它

timer = [NSTimer scheduledTimerWithTimeInterval:0.35 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
我想到的唯一方法是每次运行“
timerMethod
”时使其无效,然后为其设置一个新的随机时间,但我担心这会对性能产生影响

timer = [NSTimer scheduledTimerWithTimeInterval:0.35 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];

还有其他更好的方法吗?

使用一系列
[self-performSelector:@selector(timerMethod)with Object:nil afterDelay:
调用,而不是使用计时器。它将大致类似于尾部递归-
timerMethod
将例行地在其中的某个地方安排对自身的未来调用

timer = [NSTimer scheduledTimerWithTimeInterval:0.35 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
还要注意保持循环。
NSTimer
performSelector:…
都保留其目标。您可以在仅捕获弱引用后拒绝使用或使用
dispatch\u,或者使用近似的两阶段解除分配,其中非解除分配调用显式地使计时器无效,或者设置一个标志,告诉您不要安排另一个调用
timerMethod

timer = [NSTimer scheduledTimerWithTimeInterval:0.35 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
GCD解决方案如下所示:

timer = [NSTimer scheduledTimerWithTimeInterval:0.35 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
- (void)timerMethod
{
    // schedule the next call to timerMethod, keeping only a weak
    // reference to self so as not to extend the lifecycle
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 
                                   (int64_t)(<random value> * NSEC_PER_SEC));

    __weak typeof(self) weakSelf = self;
    dispatch_after(popTime, dispatch_get_main_queue(),
    ^{
        [weakSelf timerMethod];
    });

    // ... and do whatever else here ...
}
-(void)timerMethod
{
//安排下一次调用timerMethod,只保留一个微弱的
//引用self,以免延长生命周期
调度时间=调度时间(立即调度时间),
(国际单位)(以秒计);;
__弱类型(自我)弱自我=自我;
dispatch_after(popTime,dispatch_get_main_queue(),
^{
[weakSelf timerMethod];
});
//…在这里做任何其他事情。。。
}

如果您避免使用便利方法,而使用NSTimer init方法,则有机会设置公差

timer = [NSTimer scheduledTimerWithTimeInterval:0.35 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
另一种选择是创建makeTimer方法。在其中,如果计时器不是零,则使其无效。使用init方法创建一个新计时器并设置一个随机间隔。
使用makeTimer方法创建计时器

(我相信)没有理由为弱引用而烦恼。块没有创建保留循环。@rmaddy我不同意。假设没有弱引用。如果我至少调用了一次
timerMethod
,那么
self
将如何被释放?在块完成后,块将释放
self
。我同意@Tommy的观点,这与正常情况不同,
timerMethod
被循环调用。仅供参考-我刚刚创建了一个简单的测试应用程序,它使用这个答案中的代码(但没有弱引用)。我让
timerMethod
运行了5次并停止。然后我关闭了视图控制器,调用了
dealoc
方法。不需要弱引用。
setTolerance:
是指允许系统增加CPU睡眠时间,如果时间足够接近正确的时间(因为唤醒和睡眠不是自由的),则允许系统在唤醒时调用多个计时器;这并不意味着给你随机性。是的,但不可预测的是,在操作系统中会发生多少合并,所以这可以用来提供一些随机性。没有人说任何关于分配的事。这是一个动态的过程。
timer = [NSTimer scheduledTimerWithTimeInterval:0.35 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];