我有一个iPhone
应用程序,我希望每隔1
秒在后台执行一个方法。
所以在我的主线程中,我在UIViewController
viewDidLoad()
上有以下代码:
[NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(repeatedMethod) userInfo:nil repeats:YES];
使用以下方法:
-(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)最快的方法是什么?每次调用方法时,我都会通过调整新的后台线程来浪费时间吗?
代码工作得很好,当我在主线程上运行所有东西时,它只是相当慢一点(我最终不想这样做)。
任何建议都会很棒! 有没有人以前处理过这类问题?
非常感谢, 布雷特
答案 0 :(得分:13)
根据你评论中的问题,我想我会将我的评论扩展为一个真正的答案。您可以使用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琐碎。请参阅我对此问题的回答:Is there an advantage to using blocks over functions in Objective-C?。