后台网络电话 - iOS

时间:2011-07-28 15:26:35

标签: objective-c ios cocoa-touch asynchronous

我需要在后台实现将一些数据发布到Web服务器。只是为了澄清,“在后台”,我并不是指使用类似AsyncTaskASIHTTPRequest的{​​{{{{{{{{{{{{ 1}}方法。我需要维护一个数据队列,当用户在应用程序中工作时,线程可以异步地开始处理和发布到Web服务。

我正在寻找一些设计这样的队列的帮助,特别是在一些边缘情况下,例如用户接收呼叫,在帖子发生时退出应用程序,用户离开应用程序转到另一个一个帖子正在发生等。你会如何处理这些案件?有没有可以推荐的源代码呢?

谢谢,
的Teja。

4 个答案:

答案 0 :(得分:3)

我最近开始在自己的工作中使用NSOperationQueue来控制后台网络请求。 NSOperation处理在后台线程上异步运行任务(如网络操作)所需的大部分样板代码(如果UI更新需要,则为前台)。

它还允许跨队列的依赖;例如,我在我的应用程序中使用了两个队列:

第一个在后台安排图像下载,最大并发数为2。每个图像下载都有一个相应的完成处理程序(作为NSBlockOperation),它依赖于图像下载完成。这些操作位于[NSOperationQueue mainQueue],它在主线程上运行,允许它们更新UI(特别是相应的UIImageView)。

请注意,NSOperationNSOperationQueue不仅适用于网络请求,而是适用于可分为原子任务和同时调度的任何操作。

Here是Apple关于此主题的介绍文档。

答案 1 :(得分:2)

自己实现了类似的功能后,我建议使用服务而不是线程来进行网络调用。这样即使你的活动被杀,你也确定你的网络电话会被执行。

然后为了实现队列,我建议你看一下IntentService(http://developer.android.com/reference/android/app/IntentService.html)

来自文档:

  

IntentService是处理异步的Services的基类   请求(表示为Intents)。客户端发送请求   通过startService(Intent)调用;该服务根据需要启动,   使用工作线程依次处理每个Intent,并自行停止   当它用完了。

     

此“工作队列处理器”模式通常用于卸载任务   来自应用程序的主线程。 IntentService类存在于   简化这种模式并处理机制。要使用它,   扩展IntentService并实现onHandleIntent(Intent)。   IntentService将接收Intents,启动一个工作线程,并且   酌情停止服务。

     

所有请求都在一个工作线程上处理 - 它们可以作为   只要有必要(并且不会阻止应用程序的主循环),   但一次只能处理一个请求。

如果您的应用程序足够简单,您可以使用sendBroadCast()在您的活动和IntentService之间共享信息和通知

答案 2 :(得分:0)

创建一个封装线程的单例:

在对象的初始化中:

[NSThread detachNewThreadSelector:@selector(mainPosterThread) toTarget:self withObject:nil];

- (void)mainDownloaderThread
{

    if( [NSThread respondsToSelector:@selector(setThreadPriority:)] )
    {
        [NSThread setThreadPriority:0.1];
    }
    NSString *urlToDownload = nil;
    while(shouldRun)
    {
        // Take next data to post in a queue (lastObject of a NSArray for example)
        if( nextDataToPost )
        {
             // Post
        }
        else
        {
             // Sleep for some time.
        }
    }
}

当应用程序在多任务支持的设备上进入后台/前台时,您还可以拥有停止/启动线程的方法。如果不支持多任务处理,请在停止时(如果不是太长)将后期数据保存在队列中,并在开始时将其恢复。最大的挑战是管理能够在应用程序结束时取消当前上传。

答案 3 :(得分:0)

这是我在我编写的每个新应用程序中一直在完善的问题。基本上我想要的是异步的网络功能,这是我使用本机功能编写的。如果您有兴趣,我很乐意向您展示一些代码。

首先,我建议您使用委托在主线程异步而不是同步进行所有网络调用。这种方式序列化/同步/并发不是问题。由于类是网络代理,我只发送一个类到新连接有新委托实例的位置。

[[NSURLConnection alloc] initWithRequest:request delegate:del] autorelease];

e.g.
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data