【问题标题】:Optional arguments in Objective-C 2.0?Objective-C 2.0 中的可选参数?
【发布时间】:2010-10-08 08:27:31
【问题描述】:

在 Objective-C 2.0 中,是否可以创建一个参数是可选的方法?也就是说,你可以有这样的方法调用:

[aFraction print];

还有这个:

[aFraction print: someParameter];

在同一个程序中。

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

更新: 好的,我刚刚做了两个方法,都叫“print”。

标题

-(void) print;
-(void) print: (BOOL) someSetting; 

实现

-(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");
    }
}

相关的程序行

    ...
    printParamFlag = TRUE;

// no parameter
    [aCodeHolder print];

// single parameter
    [aCodeHolder print:printParamFlag];
    ...

我不敢相信这有效。有什么理由我不应该这样做吗?

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    你可以声明多个方法:

    - (void)print;
    - (void)printWithParameter:(id)parameter;
    - (void)printWithParameter:(id)parameter andColor:(NSColor *)color;
    

    在实现中你可以这样做:

    - (void)print {
        [self printWithParameter:nil];
    }
    
    - (void)printWithParameter:(id)parameter {
        [self printWithParameter:nil andColor:[NSColor blackColor]];
    }
    

    编辑:

    请不要同时使用printprint:。首先,它没有表明参数是什么,其次没有人(ab)以这种方式使用Objective-C。大多数框架都有非常清晰的方法名称,这是使 Objective-C 编程如此轻松的一件事。普通的开发者是不会想到这种方法的。

    还有更好的名字,例如:

    - (void)printUsingBold:(BOOL)bold;
    - (void)printHavingAllThatCoolStuffTurnedOn:(BOOL)coolStuff;
    

    【讨论】:

    • 当我将 nil 作为参数传递时,我收到一条警告:“传递 'print:' 的参数 1 从指针中生成整数而不进行强制转换”。我应该忽略它吗?
    • 您能发布出现此错误的行吗?我不确定你在做什么。不应发生此错误。
    • 如果参数类型为 (id),则可以使用 NIL。在我的代码中,参数类型是(BOOL)。解决方案是将 NIL 更改为 0,因为这是预期的类型。我现在明白了。多种方法很棒。
    • 在您的具体情况下使用 NO 而不是 0。BOOL 不应为 0 或 1,而应为 NO 和 YES。
    • 哦,我明白了。所以 Obj-C 中的“方法名”只是参数说明符的串联列表。
    【解决方案2】:

    你做这件事的方式是在 Objective-C 中做这件事的正确方式。它在 Cocoa 中被广泛使用。例如,一些 NSString 的初始化器:

    – initWithFormat:  
    – initWithFormat:arguments:  
    – initWithFormat:locale:  
    – initWithFormat:locale:arguments:
    

    之所以起作用是因为:是方法名称的一部分,所以就编译器而言,printprint:是完全不同的消息,它们之间的联系并不比“打印”更紧密和“冲刺”。

    但是,您给出的方法的特定名称不是一个很好的例子,因为从名称中不清楚参数是什么(或者如果参数是对象打印的,“打印”本身意味着什么)。最好有printFalseMessageprintMessageWithFlag:

    【讨论】:

      【解决方案3】:

      稍微相关的是你可以有可选的参数。这意味着您可以根据需要调用带有任意数量参数的方法。但这是 C (varargs) 的一个特性。

      例如,NSArray 消息:

      + (id)arrayWithObjects:(id)firstObj, ...
      

      使用示例:

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

      这直接来自 Apple 文档。你用 nil 表示你所有论点的结束。

      【讨论】:

      • 使用它来表示可选参数而不是一个参数的可变长度列表是非常不正当的。
      • 如何声明方法的类型?
      • + (id)arrayWithObjects:(NSArray *)params;
      • @youshunei 变量参数列表通过方法声明中的三个点(“...”)指定,并通过 va_list、va_start() 和 va_end() 命令访问(可能还有其他命令? )。在 Adam 的示例中,firstObj 实际上是与 ... 指定的变量参数列表分开的参数,并且以 nil 结尾的参数列表是特定于 NSArray 的 arrayWithObjects: 方法的实现,而不是变量参数列表的一般规则.有关不需要 nil 值的示例,请参见 [NSString stringWithFormat:]。
      【解决方案4】:

      多个可选参数的另一个选项是将它们全部传递到一个 NSDictionary 中:

      - (void)someMethodWithOptions:(NSDictionary *)options;
      

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

      - key1, value must be a BlahObject
      - key2, value must be a NonBlahObject
      

      然后您可以允许任何键不存在,甚至字典本身也可以为零。

      【讨论】:

      • 这在 Ruby 中很常见。但是,在 ObjC-Cocoa 中创建字典有点冗长,因此通常最好将其保存为大量相关选项,而不是将其用作参数传递的“快捷方式”——它更像是一条风景路线。你也会失去类型检查。
      • 我认为 Apple 也将它用于某些方法,例如在字符串中。
      【解决方案5】:

      为避免解析问题:'aVariable' 用作前一个参数的名称,而不是作为选择器的一部分,您应该从编译器获得警告:

      - (void)printWithParameter:(BOOL)sv color:(NSColor *)color{
         // your cool code goes here
         if ( sv ) {
            NSLog(@"cool stuff turned on");
         }
         else {
            NSLog(@"cool stuff turned off");
         }
      }
      

      你可以调用方法,比如:

      [self printWithParameter:NO color:[UIColor someColor]] // NO instead of 0
      

      [self printWithParameter:YES color:[UIColor someColor]] // YES instead of 1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-24
        • 1970-01-01
        • 1970-01-01
        • 2010-10-05
        • 1970-01-01
        • 2013-01-26
        • 2012-10-08
        相关资源
        最近更新 更多