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

发布于 2024-11-08 07:35:27 字数 2183 浏览 0 评论 0原文

我是 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我三岁 2024-11-15 07:35:28

在这种情况下你不需要 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.

雾里花 2024-11-15 07:35:27

答案是使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文