如何在使用 Cocoa NSDirectoryEnumerator 列出目录内容时显示文件或进度?
我是 Cocoa/Objective-C 的新手。我正在使用 Xcode 4(并且需要垃圾收集)为 Mac OS X 10.6 进行编码。
我如何使以下代码成为可能(基于Apple的示例代码) 更新我的 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);
}
}
I'm new to Cocoa/Objective-C. I'm coding for Mac OS X 10.6 using Xcode 4 (and Garbage Collection required).
How would I make it possible for the following code (based on Apple's sample code) to update my GUI so that the GUI shows either a count of the files being listed or the filenames themselves? I already know that I can't just create an outlet to a label and update the label's text. Where the NSLog
calls are made are places where I might want to update a status in the GUI.
I'm guessing that this would involve putting the task on some other process/thread? I've done some reading on multiprocessing using NSTask, multithreading and GCD. Apart from multithreading (which I want to avoid), I do not really know which I should use. I think I could knock something together but would prefer to do it an optimal or recommended way (and implement it quickly).
My impression is that NSTask will be suitable for my simple requirements?
I will also want to give the user the option to pause or cancel the long-running task.
Thanks in advance.
Code:
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);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在这种情况下你不需要 NSTask。了解事件架构。如果您正确组装了各个部分,那么您仍然可以在运行枚举等过程时响应用户事件。尝试一下。
You do not need NSTask in this case. Read about the Event Architecture. If you have assembled the parts correctly, you can still respond to user events while running a process like enumeration. Try it.
答案是使用 NSOperation,如 NSOperationSample 中所示。这涉及到将枚举放入 NSOperation 中,将其放在队列中,并让枚举循环发布 NSNotifications,窗口控制器注册以观察这些通知,以便 GUI 可以更新计数器和文件名表(建议的事件架构不太可能这样做)以便于在枚举器查找文件时方便地i)。在枚举循环内,它检查 isCancelled 标志以查看用户是否单击了 GUI 中的“停止”按钮,如果是,则退出枚举。
The answer is to use NSOperation as demonstrated in NSOperationSample. This involves putting the enumeration inside an NSOperation, placing it on the queue, and having the enumeration loop post NSNotifications which the window controller is registered to observe so that the GUI can update a counter and table of filenames (which the suggested events architecture was unlikely to facilitate readilyi) as the enumerator finds the files. Inside the enumeration loop, it checks the isCancelled flag to see if the user clicked a "Stop" button in the GUI and breaks out of the enumeration if yes.