【问题标题】:Objective-C Default Argument ValueObjective-C 默认参数值
【发布时间】:2010-10-26 16:29:27
【问题描述】:
你好,这里有一个快速的问题。我确信有一个简单的答案。
来自 PHP,我习惯于用这样的默认参数值声明一个函数:
function myFunction ($array, $sort = FALSE) {
}
如果未填充排序参数,函数将继续使用默认值 false。在 Obj-C 中,有没有类似的东西?
我正在完成我的“Objective-C 2.0 编程”一书中的练习,它希望我重新编写一个分数类打印函数以默认不减少分数,但如果值为 TRUE给出减少,继续减少分数,然后打印。这一章(书中也没有任何地方)提供了有关这方面的任何信息。
感谢你们的帮助:D
【问题讨论】:
标签:
php
objective-c
function
class
methods
【解决方案1】:
Objective-C 本身不存在默认参数。他们不能,因为参数计数与方法名称密不可分——每个冒号对应一个参数。
Objective-C 程序员通过创建“方便”方法来实现类似的目标,这些方法只是调用一个更“原始”的方法,其中一些参数填充了默认值。例如,-[NSArray indexOfObject:] 可以实现为 -[NSArray indexOfObject:inRange:] 的版本,inRange: 部分的参数为 NSMakeRange(0, [self count])。
不过,在这种情况下,我认为您的书并没有提到这一点。我认为这只是意味着如果为 reduce: 参数给出 YES 则减少分数,如果给出 NO 则不减少它。
【解决方案2】:
有两种标准模式可以实现你想要的。
(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 将使用内部定义的默认配置读取文件的内容。该默认配置可能会随着时间而改变。
【解决方案3】:
这个问题很老了,但万一有人发现它,PHP 代码的 Objective-C 版本(假设这是在一个类中)可能是这样的:
-(id)myFunction:(NSArray*)array {
return [self myFunction:array withSort:FALSE];
}
-(id)myFunction:(NSArray*)array withSort:(BOOL)useSort {
// CODE
}
我使用 (id)s,因为您的 PHP 代码中没有数据类型信息。将 (id) 替换为实际的数据类型是明智的。
【解决方案4】:
可怕的 necro,但对于任何在谷歌上搜索的人,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) {
// ...
}
请注意,该属性必须在函数的所有定义和声明中指定。
【解决方案5】:
不,默认参数是 C++ 的一个特性,而不是 C 或 Objective-C。
您在 Objective-c 中必须做的事情如下(使用上面的伪代码):
function myFunction ($array, $sort)
function myFunction ($array)
// call myFunction($array, FALSE)
【解决方案6】:
您可以使用#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]