Objective-C 2.0中的可选参数?

wil*_*lc2 52 objective-c

在Objective-C 2.0中,是否可以创建一个参数是可选的方法?也就是说,您可以进行如下方法调用:

[aFraction print];
Run Code Online (Sandbox Code Playgroud)

以及:

[aFraction print: someParameter];
Run Code Online (Sandbox Code Playgroud)

在同一个程序中.

Apple的Objective-C 2.0编程语言指南将Obj-C与Python进行了对比,似乎说这是不允许的.我还在学习,我想确定.如果它可能的,那么什么是语法,因为我的第二个代码示例不起作用.

更新: 好的,我刚刚制作了两个方法,都命名为"print".

-(void) print;
-(void) print: (BOOL) someSetting; 
Run Code Online (Sandbox Code Playgroud)

履行

-(void) print {
    [self print:0];
}

-(void) print: (BOOL) someSetting {
    BOOL sv;
    sv = someSetting;

    if ( sv ) {
        NSLog(@"cool stuff turned on");
    }
    else {
        NSLog(@"cool stuff turned off");
    }
}
Run Code Online (Sandbox Code Playgroud)

相关的计划行

    ...
    printParamFlag = TRUE;

// no parameter
    [aCodeHolder print];

// single parameter
    [aCodeHolder print:printParamFlag];
    ...
Run Code Online (Sandbox Code Playgroud)

我无法相信这有效.我有什么理由不这样做吗?

Geo*_*lly 80

您可以声明多个方法:

- (void)print;
- (void)printWithParameter:(id)parameter;
- (void)printWithParameter:(id)parameter andColor:(NSColor *)color;
Run Code Online (Sandbox Code Playgroud)

在实现中,您可以这样做:

- (void)print {
    [self printWithParameter:nil];
}

- (void)printWithParameter:(id)parameter {
    [self printWithParameter:nil andColor:[NSColor blackColor]];
}
Run Code Online (Sandbox Code Playgroud)

编辑:

请不要使用print,并print:在同一时间.首先,它不指示参数是什么,其次没有人(ab)以这种方式使用Objective-C.大多数框架都有非常清晰的方法名称,这是使Objective-C无法编程的一件事.普通开发人员不期望这种方法.

有更好的名字,例如:

- (void)printUsingBold:(BOOL)bold;
- (void)printHavingAllThatCoolStuffTurnedOn:(BOOL)coolStuff;
Run Code Online (Sandbox Code Playgroud)

  • 在您的特定情况下,使用NO而不是0. BOOL不应该是0或1,而是NO和YES. (3认同)

Chu*_*uck 16

你这样做是在Objective-C中做到这一点的正确方法.它在Cocoa中广泛使用.例如,一些NSString的初始值设定项:

– initWithFormat:  
– initWithFormat:arguments:  
– initWithFormat:locale:  
– initWithFormat:locale:arguments:
Run Code Online (Sandbox Code Playgroud)

它起作用的原因是因为它:是方法名称的一部分,因此就编译器而言,print并且print:是完全不同的消息,它们与"print"和"sprint"没有更紧密的联系.

但是,您提供的方法的特定名称对于此并不是一个非常好的情况,因为从名称中不清楚参数是什么(或者"打印"本身意味着参数是对象打印的内容).拥有,比方说,printFalseMessage和更好printMessageWithFlag:.


Mat*_*her 7

多个可选参数的另一个选项是在NSDictionary中传递它们:

- (void)someMethodWithOptions:(NSDictionary *)options;
Run Code Online (Sandbox Code Playgroud)

然后声明选项字典可能包含:

- key1, value must be a BlahObject
- key2, value must be a NonBlahObject
Run Code Online (Sandbox Code Playgroud)

然后你可以允许任何键缺席,甚至字典本身也可以是零.

  • 这在Ruby中很常见.尽管如此,在ObjC-Cocoa中创建字典有点冗长,因此通常最好将其保存为大量相关选项,而不是将其用作参数传递的"捷径" - 它更像是风景路线.你也失去了类型检查. (2认同)

Eri*_*eim 6

稍微相关的你可以有可选的参数.这意味着如果您愿意,可以使用任意数量的参数调用方法.但这是C(varargs)的一个特征.

一个例子是NSArray消息:

+ (id)arrayWithObjects:(id)firstObj, ...
Run Code Online (Sandbox Code Playgroud)

用法示例:

NSArray *myArray;
NSDate *aDate = [NSDate distantFuture];
NSValue *aValue = [NSNumber numberWithInt:5];
NSString *aString = @"a string";

myArray = [NSArray arrayWithObjects:aDate, aValue, aString, nil];
Run Code Online (Sandbox Code Playgroud)

这直接来自Apple文档.用nil表示所有参数的结束.

  • 使用它来表示可选参数而不是一个参数的可变长度列表将是非常不正常的. (2认同)