如何收集多个openFile:(NSString*)事件然后用它们做些什么?

Ste*_*own 3 macos cocoa

我正在研究Cocoa/Objective C++实用程序,并希望处理多个(即时)文件打开.要处理文件打开部分,我在我的AppDelegate.mm文件中有这个功能:

- (BOOL)application:(NSApplication*)app openFile:(NSString *)filename
{
    NSLog(@"Opening file %@", filename);

    // more C++ code here

    return YES;
}
Run Code Online (Sandbox Code Playgroud)

这些文件被发送到Quicksilver,我相信它会将这些文件一个接一个地发送到应用程序(Finder的"Open With"我想一次发送所有文件 - 所以可能使用 handleOpenApplicationEvent:(NSAppleEventDescriptor *)event可能更好地工作) - 但无论如何,该应用程序将一个接一个地接收几个文件 - 几乎是瞬间 - 但不完全在一起.这是Console.app显示的内容:

console-screenshot.png http://img109.imageshack.us/img109/1205/consolescreenshot.png

由于文件是单独发送的,但是一个接一个地发送,我的问题是如何收集所有发送的文件并对它们做一件事?例如,我想收集所有发送的文件路径,然后在对话框中一起显示它们.

我可以想到一个可能有用的概念:在接收数据时将每个文件路径存储在一个数组中.同时,当收到第一个时,在后台设置1-2秒的延迟,然后有一个对话框显示特定变量的所有内容.这个概念是正确的还是有更好的方法来做到这一点?我是Cocoa/Objective C++的新手 - 来自PHP/Perl,bash等语言.

我也希望这个帮助应用程序在完成时终止,但是如果我在等待文件,那么在收到最后一个文件时如何终止应用程序呢?

如果我添加[NSApp terminate:nil];到该applicationDidFinishLaunching函数,应用程序实际上只在收到第一个文件后终止.

更新 - 更多备注

这是使用openFiles(复数)函数后的控制台: Picture 7.png http://img24.imageshack.us/img24/5715/picture7zc.png

使用Quicksilver我会抓取一些文件,比如temp目录中的文件,然后选择"Open With",然后选择我正在创建的App(名为darn.app)

屏幕截图2012-01-18 at 7.02.45 PM.png http://img9.imageshack.us/img9/4171/screenshot20120118at702.png

但是使用Finder似乎工作得很好:

屏幕截图2012-01-18 at 7.09.08 PM.png http://img832.imageshack.us/img832/8858/screenshot20120118at709.png

...结果在consolea.app:

图8.png http://img24.imageshack.us/img24/2812/picture8fe.png

我确实问过Quicksilver的开发人员,他们确认QS确实打开一个文件,一次打开文件,他们承认这与Finder的做法不同,但他们认为这是预期的.也许Darren是对的 - 计时器可能是最好的方式......

Dar*_*ren 5

尝试实现-application:openFiles:而不是-application:openFile:

- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
{
    NSLog(@"Opening multiple files %@", filenames);
}
Run Code Online (Sandbox Code Playgroud)

处理从Finder接收多个文件.

如果这对您的Quicksilver设置不起作用,那么计时器可能是最好的方法.

在AppDelegate的-init方法中设置计时器.

@implementation MyAppDelegate {
    NSMutableArray* _files;
}

- (id)init {
    if (self = [super init]) {
        _files = [[NSMutableArray alloc] initWithCapacity:10];

        [self performSelector:@selector(processFiles) 
                   withObject:nil 
                   afterDelay:1.0]; // one second delay
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

应用程序:openFile:收集数组中的文件并重置计时器.

- (BOOL)application:(NSApplication*)app openFile:(NSString*)filename {
    NSAssert(_files != nil, @"Timer already fired");

    [_files addObject:filename];

    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    [self performSelector:@selector(processFiles) 
               withObject:nil 
               afterDelay:1.0];
} 
Run Code Online (Sandbox Code Playgroud)

当计时器触发时,处理收集的文件,然后退出应用程序.

-(void)processFiles

    // Process the _files

    [_files release];
    _files = nil;
    [NSApp terminate:nil];
}
Run Code Online (Sandbox Code Playgroud)