基本上,我有一个方法需要几秒钟才能完成,因为它使用NSFileManager复制一些文件。当用户选择可拖动的UIView图标时,会在touchesMoved事件上调用此方法。但是,在图标位置更新之前会有一点延迟。在继续之前,我猜它正在等待该方法复制它的文件。该方法必须在touchesMoved上触发,所以请不要建议移动它。
如何在不举起代码的情况下执行需要大约一秒钟才能完成的方法?
(..并且不要担心复制方法不会从touchesMoved事件中反复调用)
答案 0 :(得分:3)
您可以使用performSelectorInBackground:...
在后台执行任务:
这可以防止选择器阻塞主线程。
示例:
[self performSelectorInBackground:@selector(myMethod) withObject:nil];
答案 1 :(得分:1)
在后台线程中执行此操作。保留主线程仅处理UI内容。
答案 2 :(得分:1)
从技术上讲,您可以将文件复制划分为非常小的块,并告诉当前NSRunLoop
在每个文件副本之间进行分派。
但实际上只是对主线程上的任何IO访问说不,所有 IO访问应该在后台完成。即使主线程上最轻微的阻塞也会使用户界面断断续续并且没有反应,Android用户可能会接受,iOS用户不会。
您的选择众多且易于实施。你可以做一个简单的performSelector–
:
-(void)backgroundWorker {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Do your stuff
[pool release];
}
-(void)startDoingIOStuff {
[self performSelectorInBackground:@selector(backgroundWorker)
withObject:nil];
}
你可以使用块和GCD实际内联:
-(void)startDoingIOStuff {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL),
^{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Do your stuff
[pool release];
});
}
或者您可以在NSOperation
上使用NSOperationQueue
。我已经写了一篇关于这个主题的博文,包括可在此处获得的源代码:http://blog.jayway.com/2010/08/19/future-cocoa-operation/
答案 3 :(得分:0)
在立即使用辅助线程之前,尝试在自己上使用普通的performSelector肯定是值得的。例如:
[self peformSelector:@selector(copyFiles) withObject:nil afterDelay:0.0];
请注意,这与做:
不同[self copyFiles];
peformSelector版本基本上说“尽快复制文件,好吗?”,但是在等待它完成时不会阻止所有内容。换句话说,执行选择器版本可能允许主事件循环在实际完成文件复制之前更新UI(从而防止明显的视觉延迟)。