Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iPhone SDK-在后台线程中运行重复进程_Iphone_Objective C_Multithreading_Cocoa Touch_Nsthread - Fatal编程技术网

iPhone SDK-在后台线程中运行重复进程

iPhone SDK-在后台线程中运行重复进程,iphone,objective-c,multithreading,cocoa-touch,nsthread,Iphone,Objective C,Multithreading,Cocoa Touch,Nsthread,我有一个iPhone应用程序,我想每隔1秒在后台执行一个方法 因此,在我的主线程中,我在我的UIViewControllerviewDidLoad()上有以下代码: 采用以下方法: -(void)repeatedMethod { if(!processIsRunning) { processIsRunning = YES; [self performSelectorInBackground:@selector(runProcessInBackground:) withObje

我有一个
iPhone
应用程序,我想每隔
1
秒在后台执行一个方法

因此,在我的主线程中,我在我的
UIViewController
viewDidLoad()
上有以下代码:

采用以下方法:

-(void)repeatedMethod {
  if(!processIsRunning) {
    processIsRunning = YES;
    [self performSelectorInBackground:@selector(runProcessInBackground:) withObject:myImage];
  }
}

-(void)runProcessInBackground:(UIImage *)image {
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

  ... Some operations ...
  ...   also call a method on the main thread which sets isProcessRunning to NO

  [pool release]
}
按照我的设置方式,每秒都会产生一个新线程(除非由于我的
processIsRunning
标志,进程仍在运行)

现在,我的问题是:

(1) 这是最好的方法吗?或者有没有更合适的方法来保留和重用后台线程

(2) 最快的方法是什么?每次调用该方法时,我都会旋转新的后台线程,这是不是在浪费时间

代码运行得很好,只是当我在主线程上运行所有东西时(这是我最终不想做的)会慢一点

任何建议都很好! 以前有人处理过这类问题吗

非常感谢,,
Brett

基于你评论中的问题,我想我应该把我的评论扩展成一个真实的答案。您可以使用GCD来实现这一点,这可能是最好的方式

大概是这样的:

dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, backgroundQueue);
dispatch_source_set_timer(timerSource, dispatch_time(DISPATCH_TIME_NOW, 0), 1.0*NSEC_PER_SEC, 0*NSEC_PER_SEC);
dispatch_source_set_event_handler(timerSource, ^{
    [self repeatedMethod];
});
dispatch_resume(timerSource);

- (void)repeatedMethod {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [self doStuffWithAnImage:self.myImage];   

    [pool drain];
}

关于块最酷的事情之一是它们捕获了局部范围。在我上面的示例中,实际上没有使用它,但它使将对象“传递”到GCD变得微不足道。看看我对这个问题的回答:。

看看我对这个问题的回答:@Andrew,谢谢!但有一个问题:我如何通过GCD传递对象?在我上面的代码中,这个对象将是“myImage”。这实际上是非常有用的!非常感谢。但这引出了最后一个问题(希望如此)。在您对另一个问题的参考答案中,您表明该块将在创建时保留本地范围(即,在您的另一个答案中num1=42)。在我的例子中,我希望在主线程上不时更新self.image。[self dostufwithanimage:self.myImage]能够访问最新的映像(由主线程设置),还是保留GCD线程创建时存在的self.image?再次感谢
self.myImage
相当于
[self-myImage]
。由于它实际上是在调用
-myImage
访问器方法,因此它将在执行块时获取并使用当前值。在任何情况下,该调用都是在repeatedMethod中进行的,该方法由块调用。块捕获直接在块体中使用的变量,但它们不会通过调用的方法递归下降并捕获其中的作用域(这没有意义,因为方法中的变量位于堆栈上,并且在调用方法之前不存在)。简而言之,它将获得最新的myImage。我应该补充一个事实,即您将在一个线程中设置myImage,并在另一个线程中读取(可能设置它?),这意味着您需要注意线程安全。只要您只是在后台阅读,而不是设置它,那么只需将@property设置为原子属性就可以了。如果您需要从后台设置,最简单的方法可能是将set调用发送回主线程。这是非常棒的东西,谢谢。我刚刚学到了很多。我确实需要从后台线程将isProcessRunningFlag设置为NO。为此,我需要调度set回调?像这样:?dispatch_async(dispatch_get_main_queue(),^{isProcessRunning=NO;});嗯……我刚刚编译并运行了一个非常简单的测试程序,使用了我答案中的代码(在我的Mac上,而不是在iOS上),它运行得很好,所以我不确定问题出在哪里。
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, backgroundQueue);
dispatch_source_set_timer(timerSource, dispatch_time(DISPATCH_TIME_NOW, 0), 1.0*NSEC_PER_SEC, 0*NSEC_PER_SEC);
dispatch_source_set_event_handler(timerSource, ^{
    [self repeatedMethod];
});
dispatch_resume(timerSource);

- (void)repeatedMethod {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [self doStuffWithAnImage:self.myImage];   

    [pool drain];
}