执行一个需要一秒钟才能完成而不会暂时停止代码的方法

时间:2010-11-17 22:09:33

标签: iphone objective-c file copy delay

基本上,我有一个方法需要几秒钟才能完成,因为它使用NSFileManager复制一些文件。当用户选择可拖动的UIView图标时,会在touchesMoved事件上调用此方法。但是,在图标位置更新之前会有一点延迟。在继续之前,我猜它正在等待该方法复制它的文件。该方法必须在touchesMoved上触发,所以请不要建议移动它。

如何在不举起代码的情况下执行需要大约一秒钟才能完成的方法?

(..并且不要担心复制方法不会从touchesMoved事件中反复调用)

4 个答案:

答案 0 :(得分:3)

您可以使用performSelectorInBackground:...在后​​台执行任务:

http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html

这可以防止选择器阻塞主线程。

示例:

[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(从而防止明显的视觉延迟)。