我正在研究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是对的 - 计时器可能是最好的方式......
尝试实现-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)