如何停止在后台执行选择器? [英] how to stop performing selector in background?

查看:40
本文介绍了如何停止在后台执行选择器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个A类.在这个类中,我有一个方法,会调用[ self performSelectorInBackground:...] .然后开始下载来自互联网的一些信息.

I have some class A. In this class i have a method, which calls [self performSelectorInBackground:...]. And it starts downloading some info from internet.

当我点击主页"按钮,然后再次进入应用程序后,此后台方法将继续起作用.因此,如果我再次调用此方法,则我具有bad_access权限,因为后台方法已经在工作,并且我调用了两次.

After i tap Home button, then enter the app again, this background method keeps working. So, if i call this method again, i have bad_access, because background method is already working and i call it twice.

我可以在A类背景下停止执行选择器吗?例如在我的applicationDidEnterBackground吗?或者我可以检查选择器是否正在执行操作?

Can i stop performing selector in background of the class A? For example in my applicationDidEnterBackground? Or can i check, if selector is performing or something?

我发现了一些类似的东西

I found couple things like

[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:a];
[NSObject cancelPreviousPerformRequestsWithTarget:a selector:@selector(startDownload) object:nil];

但是他们没有为我工作.所以

But they didn't work for me. So

我的objAppDelegate:

my objAppDelegate:

@inteface ObjAppDelegate
{
     A *a;
}
@implementation ObjAppDelegate
{
    -(void)applicationDidEnterBackground:(UIApplication *)application
    {
        //or it can be didBecomeActive..
        //here. check if background task of class A is running, or just stop it ??
    }
}

@implementation A
{
     //some timer, or event, etc.
     -(void)startDownload
     {
          [self performSelectorInBackground:@selector(runBackgroundTask)           withObject:nil];
      }
    -(void)runBackgroundTask
    {
         //some network stuff..
     }
}

我这样做是这样的:


threadForDownload = [[NSThread alloc] initWithTarget:self selector:@selector(threadMain:) object:nil];
            [threadForDownload start];
            [self performSelector:@selector(startDownload) onThread:threadForDownload withObject:nil waitUntilDone:NO];
  • (void)threadMain:(id)data {NSAutoreleasePool * pool = [NSAutoreleasePool new];

  • (void)threadMain:(id)data { NSAutoreleasePool *pool = [NSAutoreleasePool new];

NSRunLoop * runloop = [NSRunLoop currentRunLoop];[runloop addPort:[NSMachPort端口] forMode:NSDefaultRunLoopMode];

NSRunLoop *runloop = [NSRunLoop currentRunLoop]; [runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];

同时(是){[runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];}

while (YES) { [runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; }

[池释放];}

在我的startDownload方法中,我查看活动指示器以检查是否startDownload已经在运行..

In my startDownload method i look at activity indicator to check, whether startDownload is already running..


-(void)startDownload
{
       if (![[UIApplication sharedApplication] isNetworkActivityIndicatorVisible])  // flag..
    {
            //....
         }
}

//每次我开始下载时,我都会显示networkActivityIndi​​cator

// I make visible networkActivityIndicator every time i start downloading

推荐答案

这是要做的事情:

  1. 后台任务使用
  1. the background task saves its thread to a property somewhere using NSThread currentThread
  2. the background task periodically checks the thread's isCancelled property.
  3. the main thread sends cancel to the thread object saved by the background thread in step 1.
  4. On exit, the background thread sets the property to nil.

用于存储线程的属性的所有操作都必须受 @synchronized 或同等保护,以防止主线程将 cancel 发送给已取消分配的对象线程对象.

All of the operations on the property used to store the thread in have to be protected by @synchronized or equivalent to prevent the main thread from sending cancel to a deallocated thread object.

后台线程不能执行阻塞时间超过一小段时间的IO操作.特别是,使用NSURLConnection的URL的同步下载已退出.如果使用NSURLConnection,则需要转到异步方法和运行循环(可以说,在这种情况下,您可以完全取消后台线程).如果您使用的是POSIX级别的IO,请在超时的情况下使用 poll().

The background thread can't do IO operations that block for more than a short period of time. In particular, synchronous downloading of URLs using NSURLConnection is out. If you are using NSURLConnection, you'll want to move to the asynchronous methods and a run loop (arguably, in that case, you can do away with the background thread altogether). If you are using POSIX level IO, use poll() with a timeout.

这篇关于如何停止在后台执行选择器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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