如何使用Cocoa NSDirectoryEnumerator列出目录内容时显示文件或进度?

时间:2011-05-18 20:06:30

标签: objective-c cocoa macos

我是Cocoa / Objective-C的新手。我正在使用Xcode 4编写Mac OS X 10.6(需要垃圾收集)。

如何使以下代码(基于Apple的sample code)更新我的GUI,以便GUI显示列出的文件数或文件名本身?我已经知道我不能只为标签创建一个插座并更新标签的文本。进行NSLog调用的地方是我可能想要在GUI中更新状态的地方。

我猜这会涉及将任务放在其他进程/线程上?我已经使用NSTask,多线程和GCD对多处理进行了一些阅读。除了多线程(我想避免),我真的不知道应该使用哪个。我想我可以把一些东西拼在一起,但更愿意以最佳或推荐的方式(并快速实施)。

我的印象是NSTask适合我的简单要求吗?

我还想让用户选择暂停或取消长时间运行的任务。

提前致谢。

代码:

NSArray *keys = [NSArray arrayWithObjects:
    NSURLIsDirectoryKey, NSURLIsPackageKey, NSURLLocalizedNameKey, nil]; 

NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] 
                                    enumeratorAtURL:directoryURL
                         includingPropertiesForKeys:keys 
                                            options:(NSDirectoryEnumerationSkipsHiddenFiles) 
                                       errorHandler:^(NSURL *url, NSError *error) { 
                                           // Handle the error.
                                           // Return YES if the enumeration should continue after the error. 
                                     return YES; 
                                       }
                                    ]; 

for (NSURL *url in enumerator) { 
    // Error-checking is omitted for clarity. 

    NSNumber *isDirectory = nil; 
    [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:NULL]; 

    if ([isDirectory boolValue]) { 
        NSString *localizedName = nil; 
        [url getResourceValue:&localizedName forKey:NSURLLocalizedNameKey error:NULL]; 

        NSNumber *isPackage = nil; 
        [url getResourceValue:&isPackage forKey:NSURLIsPackageKey error:NULL]; 

        if ([isPackage boolValue]) { 
            NSLog(@"Package at %@", localizedName); 
        } 
        else { 
            NSLog(@"Directory at %@", localizedName); 
        }
    }
    else {
        NSLog(@"File at %@", url);
    }
}

2 个答案:

答案 0 :(得分:1)

答案是使用NSOperationSample中所示的NSOperation。这涉及将枚举放在NSOperation中,将其放在队列中,并在窗口控制器注册的NSNotifications之后进行枚举循环观察,以便GUI可以更新计数器和文件名表(建议的事件架构不太可能)在枚举器找到文件时便于使用。在枚举循环中,它检查isCancelled标志以查看用户是否在GUI中单击了“停止”按钮,如果是,则突破枚举。

答案 1 :(得分:0)

在这种情况下,您不需要NSTask。阅读Event Architecture。如果已正确组装了部件,则仍可在运行枚举等过程时响应用户事件。试试吧。