在Objective-C应用程序之间传递参数

时间:2012-05-15 13:27:56

标签: objective-c cocoa arguments

我想知道是否可以在Mac应用程序之间传递参数,如果可能的话,如何传递参数。

我知道在Java中可以使用命令行中的以下语法:

  

java JavaApp arg1 arg2 arg3 arg4

可以通过main的args []数组访问那些。

public static void main(String[] args) {
        System.out.println("d");
        for (int i = 0; i < args.length; i++)
            System.out.println(args[i]);
}

编辑:我想将参数从命令行 Mac应用程序传递到 Cocoa Mac 应用程序

4 个答案:

答案 0 :(得分:3)

我不清楚为什么您的Restarter应用程序需要是Cocoa应用程序。但是,假设确实如此,命令行参数在NSUserDefaults的参数域中可用。 This link显示了如何从命令行调用程序以及如何指定默认名称。

Cocoa启动单独流程的方法是使用NSTask

答案 1 :(得分:1)

如果命令行和GUI应用程序都是用Objective-C编写的,那么您可以使用NSDistributedNotificationCenter在进程之间发送通知。可以在Notification Programming Guide

中找到NSDistributedNotificationCenter的文档

或者,Cocoa GUI应用程序接受命令行参数的方式与任何其他C程序相同,即argv子例程的argcmain参数。< / p>

答案 2 :(得分:1)

以下是我在NSWorkspace上编写的类别,它允许将argv类型的参数数组传递给生成的应用程序。

@interface NSWorkspace (MDAdditions)
- (BOOL)launchApplicationAtPath:(NSString *)path
                      arguments:(NSArray *)argv
                          error:(NSError **)outError;
@end

@implementation NSWorkspace (MDAdditions)

- (BOOL)launchApplicationAtPath:(NSString *)path
                      arguments:(NSArray *)argv
                          error:(NSError **)outError {
    NSParameterAssert(path != nil);
    BOOL success = YES;
    if (outError) *outError = nil;
    FSRef itemRef;
    OSStatus status = FSPathMakeRef((const UInt8 *)[path UTF8String], &itemRef, NULL);
    if (status != noErr) {
        if (anError) *anError = [NSError errorWithDomain:NSOSStatusErrorDomain
                        code:status userInfo:nil];
        return NO;
    }
    LSApplicationParameters appParameters = {0, kLSLaunchDefaults, &itemRef,
         NULL, NULL, (argv ? (CFArrayRef)argv : NULL), NULL };
    status = LSOpenApplication(&appParameters, NULL);
    if (status != noErr) {
         NSLog(@"LSOpenApplication() returned %d for %@", (int)status, path);
         if (outError) *outError = [NSError errorWithDomain:NSOSStatusErrorDomain
                        code:status userInfo:nil];
         return NO;
    }
    return YES;
}
@end

更新:

正如Accessing command-line arguments in Objective-C的答案中所述,__NSGetArgv()函数的“_NSGetArgc()”前缀通常表示它们是私有的,应该避免使用如果有替代品(有),

要将args传递给可执行文件,您可以使用NSProcessInfo-arguments方法,如下面的代码所示:

NSArray *argv = [[NSProcessInfo processInfo] arguments];
NSArray *args = [argv subarrayWithRange:NSMakeRange(1, argv.count - 1)];
NSLog(@"args == %@", args);

答案 3 :(得分:0)

您的所有答案都适合我,但我找到了另一种更适合我需求的解决方案。 我需要从命令行工具启动一个Cocoa应用程序,我通过以下行来实现:

system("nohup /PATH/Arguments.app/Contents/MacOS/Arguments argument1 argument2 &");

nohup 是一个unix服务,允许您将进程附加到自身,因此如果关闭终端窗口,该进程将保持活动状态。

接下来出现的问题是从Cocoa应用程序中捕获参数。 “如果AppDelegate.m是接收它们的那个并且只返回一个int,我将如何从main.m获取参数。”

在Apple的框架和库中,我找到了一个可以解决问题的方法。这个库名为crt_externs.h,包含两个有用的变量,一个用于学习参数的数量,另一个用于获取参数本身。

extern char ***_NSGetArgv(void);
extern int *_NSGetArgc(void);

因此,在Cocoa应用程序的 AppDelegate的中,我们将编写以下代码来将参数解析为 NSString的

char **argv = *_NSGetArgv();
NSString *argument1 = [NSString stringWithCString:argv[1] encoding:NSUTF8StringEncoding];
NSString *argument2 = [NSString stringWithCString:argv[2] encoding:NSUTF8StringEncoding];

正如我们所看到的,我们直接跳到arguments数组的位置1,因为位置0包含路径本身:

argv[0] = '/PATH/Arguments.app/Contents/MacOS/Arguments'
argv[1] = 'argument1'
argv[2] = 'argument2'

谢谢大家的时间和帮助。我从你们那里学到了很多东西。我也希望这个答案有助于其他人:)

欢呼和快乐的编码!

相关问题