iOS使用GCD或NSThread进行长时间运行吗? [英] iOS Long Running Operation using GCD or NSThread?

查看:70
本文介绍了iOS使用GCD或NSThread进行长时间运行吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是iOS开发的新手(我最熟悉Java),我想知道启动长时间运行的线程的最佳方法是什么?只要应用程序在前台,该线程就会启动,而在后台时,它将停止.当它处于前台时,它将每隔X秒轮询一次外部设备,看其是否已连接.

I am new to iOS development (I'm most familiar with Java), and I was wondering what is the best method for starting a long running thread? This thread is going to start whenever the application is in the foreground and will stop when it goes to the background. While it is in the foreground, it is going to poll an external device every X seconds to see if if it connected.

NSThread与Java线程类非常相似,这使我很容易理解.我知道我可以只 initWithTarget:selector:object:该类并调用 start:,它将使用选择器中提供的方法启动线程.在这里,我只有一个 while(true)循环,该循环一直运行,直到我脱离它为止.这是我要执行的操作的基本示例:

NSThread is very similar to the Java thread class, which makes it very easy for me to understand. I know that I can just initWithTarget:selector:object: that class and call start: and it'll start up the thread with the method supplied in the selector. In there I just have a while(true) loop that keeps on running until I break out of it. Here is a basic example of what I'm looking to do:

- (void)startup {
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(devicePoller) object:nil];
    [thread start];
}

- (void)devicePoller {
    while (self.started) {
        if (![self.device isConnected]) {
            //notify the user the device isn't connected
        }

        [NSThread sleepForTimeInterval:2];
    }
}

但是,我看到人们建议使用GCD,因为它具有更好的性能.我知道如何使用 dispatch_async()异步执行代码,但是所有示例似乎都是针对单个长时间运行的操作,而不是针对整个应用程序运行的操作.是否可以使用GCD(我应该)或其他方法来做到这一点?

However, I am seeing that people recommend using GCD because it has better performance. I understand how to use dispatch_async() for executing code asynchronously, but all of the examples out there seem to be for a single long running operation, not an operation that runs the entire time the application is running. Is there a way to do this with GCD (and should I) or something else?

推荐答案

如果您需要轮询并且想在后台线程上进行轮询,那么我建议使用一个调度计时器:

If you needed to poll and you want to do it on a background thread, I might suggest a dispatch timer:

@property (nonatomic, strong) dispatch_source_t timer;

,然后您可以将此计时器配置为每两秒触发一次:

and you can then configure this timer to fire every two seconds:

dispatch_queue_t queue = dispatch_queue_create("com.domain.app.devicepoller", 0);
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(self.timer, dispatch_walltime(NULL, 0), 2.0 * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC);
dispatch_source_set_event_handler(self.timer, ^{
    [self pollDevice];    // this method should just poll the device and then return; no loop needed in this method
});
dispatch_resume(self.timer);

请参阅但是大多数设备都支持某种形式的事件驱动通知,从而避免了像这样进行任何轮询的需要,但是如果必须进行轮询,并且如果要在主线程之外进行轮询,则这是一种实现方法

But most devices support some form of event-driven notification that obviates the need for any polling like this, but if you have to poll, and if you want to do it off the main thread, this is one way to do it.

当您希望计时器在后台队列上运行时,分派计时器非常有用.如果供应商的API具有足够的响应能力,可以在主队列中无缝运行,请使用 NSTimer 方法.它使您不必要做很多额外的工作即可使代码具有线程安全性(例如,正确的

The dispatch timer is useful when you want a timer to run on a background queue. If your vendor's API is responsive enough to run seamlessly in the main queue, then use NSTimer approach. It keeps you from having to do a lot of extra work to make your code thread-safe (e.g. proper synchronization as you update model objects, etc.). I assumed from your original question's thread-based approach that you had some reason to not use a timer and you had to move it to another thread for some reason, in which case I contend that a dispatch timer might be a better way to handle it than doing NSThread programming with a perpetual while loop. But if you (a) have to poll; and (b) don't have a compelling need to write multi-threaded code, then your life may be simpler if you used NSTimer-based approach.

就我个人而言,请确保已用尽

Personally, I'd make sure I exhausted the Core Bluetooth approach before I pursued timers. App-level polling of a physical device should be considered the approach of last resort. Perhaps you can contact the vendor of the API and see if they have suggestions other than polling (because if they've been doing this for a while, they might have more elegant solutions that they can suggest).

关于接收Web服务更新,轮询仍然非常低效(并且取决于轮询的频率,它可能会对电池寿命产生不利影响,消耗蜂窝数据计划等).推送通知服务器数据很少更改,但是您希望主动将更改通知给您的应用.或者,如果服务器确实在不断变化,那么也许可以使用一些基于套接字的方法.但是,每两秒钟轮询一次网络资源(如果这就是您的建议),通常是不正确的方法.

Regarding receiving web service updates, again polling is horribly inefficient (and depending upon frequency of your polling, it can adversely affect battery life, consume cellular data plan, etc.). Push notifications might be the way to go if the server data is changing infrequently, but you want your app to be proactively notified of changes. Or if the server is really changing constantly, then maybe some socket based approach might make sense. But polling a network resource every two seconds (if that's what you meant to suggest) is rarely the right approach.

就像轮询物理设备是万不得已的体系结构一样,对于网络通信而言,情况更是如此.您真的想提出一种架构,该架构可以平衡设备考虑因素和业务需求.而且,如果您得出结论,必须采取基于轮询的方法,那么也许您可能会考虑采用不同的轮询频率,具体取决于用户是使用wifi还是使用蜂窝电话.

Just like polling of a physical device is the architecture of last resort, this is even more true for network communications. You really want to come up with an architecture that balances to device considerations with the business need. And if you conclude you have to do a polling-based approach, perhaps you might consider employing different polling frequency depending upon whether the user is on wifi vs. cellular.

这篇关于iOS使用GCD或NSThread进行长时间运行吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆