复制文件而不冻结GUI

时间:2013-08-20 10:49:36

标签: objective-c macos cocoa

好的,基本上这就是我想要做的事情:

  • 我的应用包中有一个文件列表,例如在文件夹myData中(请注意:子文件夹/等内有很多文件/文件夹)
  • 我想将整个文件树复制到用户磁盘上的指定位置
  • 我需要访问要复制的每个单独文件,因为其中一些文件在复制之前需要进行处理。

你会怎么做?有什么想法吗?


P.S。

  • 我知道NSFileWrapper的{​​{1}},但它并不能让我访问每个文件
  • 我已经有了获取特定文件夹的文件树的方法。但是,在我看来它似乎有点慢。是否有任何内置(或更多Cocoa友好)方式?
  • 由于文件相当多,整个过程必须运行才能使GUI 冻结

1 个答案:

答案 0 :(得分:6)

使用Grand Central Dispatch(GCD)使用

以异步线程运行方法
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // user disk space - will use user document
    NSString *docuemntPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

    // app bundle folder
    NSString *bundleRoot = [[NSBundle mainBundle] resourcePath];
    NSString *folderPath = [bundleRoot stringByAppendingPathComponent:@"aFolder"];

    NSArray *files = [[NSFileManager defaultManager] enumeratorAtPath:folderPath].allObjects;

    for (NSString *aFile in [files objectEnumerator]) { 
        NSString *copyPath = [folderPath stringByAppendingPathComponent:aFile];
        NSString *destPath = [docuemntPath stringByAppendingPathComponent:aFile];

        NSError *error;
        if ([[NSFileManager defaultManager] copyItemAtPath:copyPath toPath:destPath error:&error]) {
            NSLog(@"Copying successful");
            // here add a percent to progress view 
        } else {
            NSLog(@"Copying error: %@", error.userInfo);
        } 
    }

  // When the copying is finished update your UI 
  // on the main thread and do what ever you need with the object 
  dispatch_async(dispatch_get_main_queue(), ^{
    [self someMethod:myData];
  });
});

并在您的主线程上使用UIProgressView从文件/文件夹的数量指示文件操作的进度。