gpt4 book ai didi

ios - 我什么时候应该将 Runloop 应用到我的程序中,为什么?

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:59:40 27 4
gpt4 key购买 nike

我的要求是我想每 6 秒调用一个 API 从我的服务器请求一些新信息,所以我编写了如下代码:

MyBackgroundThread(){

while(self.isStop){
[self callMyAPI];
[NSThread sleepfortimeinterval : 6 ];
}
}

但是我今天发现,Foundation 库提供了一种编写运行循环的方法。所以我可以重写我的代码如下:

MyBackgroundThread(){

NSTimer *timer = [NSTimer timerWithTimeInterval:6 target:self selector:@selector(callMyAPI) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[timer release];
while (! self.isCancelled) {
BOOL ret = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
}

但是,我不知道这些是否是比我原来的工作更好的工作方式?如果是,为什么?以及如何测试这两种方式在效率(或其他属性?)方面的差异?

谢谢!

最佳答案

我认为通常没有必要为计时器创建新的运行循环。我建议采用以下两种方法之一:

  1. 在主运行循环上安排 NSTimer,但调用方法然后将请求分派(dispatch)到后台队列。

  2. 创建计划在指定的后台调度队列上运行的调度计时器。为此,创建调度计时器属性:

    @property (nonatomic, strong) dispatch_source_t timer;

    然后实例化并启动调度计时器源以在指定的 GCD 队列上运行:

    dispatch_queue_t queue = dispatch_queue_create("com.domain.app.polltimer", 0);
    self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_source_set_timer(self.timer, dispatch_walltime(NULL, 0), kPollFrequencySeconds * NSEC_PER_SEC, 1ull * NSEC_PER_SEC);

    dispatch_source_set_event_handler(self.timer, ^{
    <#code to be run upon timer event#>
    });

    dispatch_resume(self.timer);

有时创建一个新的运行循环很有用,但在这个简单的场景中似乎没有必要。


话虽如此,使用计时器每六秒启动一次网络可能没有意义。相反,您可能希望在前一个请求完成后六秒开始下一个请求。由于各种原因,您的服务器可能无法在六秒内响应,并且您不希望并发在这些情况下构建的请求(如果您的请求异步运行,可能会发生这种情况)。

所以,我倾向于 callMyAPI 的完成 block 做一些简单的事情:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6.0 * NSEC_PER_SEC)), queue, ^{
<#code to issue next request#>
});

这完全消除了对计时器(和自定义运行循环)的需求。


最后,如果您确实需要以该频率检测系统更改,则可能建议采用非常不同的服务器架构。例如,如果您每六秒轮询一次以查看服务器上是否发生了某些变化,您可能会考虑基于套接字的实现或使用推送通知。在这两种方法中,服务器都会在重大事件发生时通知客户端应用程序,而不是应用程序像 Bart Simpson 那样坐在汽车后座上,不断地问“我们到了吗?”

适当的架构可能取决于服务器数据可能更改的频率以及客户端应用程序的要求。

关于ios - 我什么时候应该将 Runloop 应用到我的程序中,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26451876/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com