Objective-C默认参数值

14

你好,这里有一个简单的问题。我相信有一个简单的答案。

从PHP来看,我习惯于这样声明具有默认参数值的函数:

function myFunction ($array, $sort = FALSE)  {

}

如果未填充排序参数,则函数将继续使用默认值false。在Obj-C中是否有类似的功能?

我正在完成“Programming In Objective-C 2.0”一书中的练习,它要求我重新编写一个分数类打印函数,默认情况下不缩小分数,但如果给出了reduce的TRUE值,则缩小分数,然后打印。该章节(也没有书中其他地方)提供任何信息。

谢谢大家的帮助 :D


在Objective-C 2.0中,如何使用可选参数? - Georg Schölly
6个回答

26

在Objective-C中,没有默认参数这个概念。这是因为参数个数与方法名称密不可分——每个冒号都对应一个参数。

不过,Objective-C程序员可以通过创建“方便”的方法来实现类似的目标,这些方法只需调用具有某些默认值的更“基本”的方法。例如,-[NSArray indexOfObject:] 可以被实现为 -[NSArray indexOfObject:inRange:] 的一个版本,其中 inRange: 部分的参数是 NSMakeRange(0, [self count])

但是,在这种情况下,我认为你的书并不是在谈论这个。我认为它只是指如果给出YES作为reduce:参数,则将分数约简,如果给出NO,则不会约简。


10

有两种标准方法可以实现你想要的结果。

(1)编写一个多参数形式的方法,然后提供更少的参数便利版本。例如,在NSString上考虑以下方法:

- (NSComparisonResult)compare:(NSString *)string;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask
            range:(NSRange)compareRange;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask
            range:(NSRange)compareRange locale:(id)locale;

前三个方法概念上 [很可能也在实现上,我没有检查] 作为对第四个版本的调用。也就是说,-compare: 会使用适当的默认值调用 -compare:options:range:locale: 方法的三个额外参数。

(2)另一种模式是实现具有多个参数的方法,并在参数为 NULL/nil 或设置为某个指示所需默认值的值时提供默认值。NSData 中有使用此模式实现的方法。例如:

+ (id)dataWithContentsOfFile:(NSString *)path options:(NSDataReadingOptions)readOptionsMask
            error:(NSError **)errorPtr;
如果您将readOptionsMask参数设为0,则NSData将使用内部定义的默认配置读取文件内容。该默认配置可能会随时间而改变。

9
这个问题很老,但是如果有人找到它,PHP代码的Objective-C版本(假设这是在一个类内部)可能是这样的:
-(id)myFunction:(NSArray*)array {
  return [self myFunction:array withSort:FALSE];
}

-(id)myFunction:(NSArray*)array withSort:(BOOL)useSort {
   // CODE
}

由于您的PHP代码中没有数据类型信息,我使用了(id)s。将(id)s替换为实际的数据类型是明智的选择。


真棒,相当聪明。 - Benjamin de Bos

5

虽然已经很久没有人回复了,但是对于任何通过谷歌搜索到这里的人,Xcode 4.5支持(通过Clang)使用__attribute__((overloadable))重载C函数。

重载函数允许具有不同数量的参数,因此如果C函数适合您要做的事情,您可以使用它来获取默认参数值。

以下是一个编写不太真实的示例.h文件,其中有两个名为PrintNum的函数:

// Prints a number in the decimal base
__attribute__((overloadable)) extern void PrintNum(NSNumber *number);

// Prints a number in the specified base
__attribute__((overloadable)) extern void PrintNum(NSNumber *number, NSUInteger base);

在 .m 文件中:

__attribute__((overloadable)) 
void PrintNum(NSNumber *number) {
    PrintNum(number, 10);
}

__attribute__((overloadable))
void PrintNum(NSNumber *number, NSUInteger base) {
    // ...
}

请注意,该属性必须在函数的所有定义和声明中指定。

1
不,缺省参数是C++的一个特性,而不是C或Objective-C。
在Objective-C中,您需要执行以下操作(使用上面的伪代码):
function myFunction ($array, $sort)

function myFunction ($array)
// call myFunction($array, FALSE)

0

您可以轻松地使用#define来实现相同的效果。

您头文件中的函数:

+(NSDate*)getDateFromYear:(NSUInteger)year month:(NSUInteger)month day:(NSUInteger)day;

在头文件中添加一个参数函数的#define
#define GetDateFromYearOnly(year) [YourClassName getDateFromYear:year month:1 day:1]

然后你可以像这样使用该函数:

NSDate* 2015Date = GetDateFromYearOnly(2015);

你将会得到一个日期为2015/01/01的NSDate对象。

如果这个函数不是static,那么可以像下面这样构建一个新的函数:

-(NSDate*)GetDateFromYearOnly:(NSUInteger)year;

并调用:

[self getDateFromYear:year month:1 day:1]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接