可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Hey there, quick question here. I'm sure there's a simple answer.
Coming from PHP, I'm used to declaring a function with a default argument value like this:
function myFunction ($array, $sort = FALSE) {
}
I the sort parameter wasn't filled, the function would continue with the default value of false. In Obj-C, is there a similar thing?
I'm working through the exercises in my "Programming In Objective-C 2.0" book, and it wants me to re-write a fraction class print function to default-ly not reduce the fraction, but if the value TRUE for reduce is given, go ahead and reduce the fraction, then print. The chapter (Nor nowhere in the book) gives any information on this.
Thanks for your help guys :D
回答1:
Default arguments don't exist in Objective-C, per se. They can't really, because the argument count is inextricably tied to the method name — each colon corresponds to one argument.
Objective-C programmers accomplish a similar goal, though, by creating "convenience" methods that just call to a more "primitive" method with some of the arguments filled in with default values. For example, -[NSArray indexOfObject:]
could be implemented as version of -[NSArray indexOfObject:inRange:]
with an argument of NSMakeRange(0, [self count])
for the inRange:
part.
In this case, though, I don't think your book is talking about that. I think it simply means to reduce the fraction if YES is given for the reduce:
argument and not reduce it if NO is given.
回答2:
There are two standard patterns for achieving what you want.
(1) write a many argument form of a method and then provide fewer argument convenience versions. For example, consider the following methods on 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;
The first three are conceptually [and likely concretely, I didn't check] implemented as calls through to the fourth version. That, is -compare: calls -compare:options:range:locale: with appropriate default values for the three additional arguments.
(2) The other pattern is to implement the many argument version of the method and provide default values when an argument is NULL/nil or set to some value that indicates the default is desired. NSData has methods that are implemented with this pattern. For example:
+ (id)dataWithContentsOfFile:(NSString *)path options:(NSDataReadingOptions)readOptionsMask
error:(NSError **)errorPtr;
If you pass 0 for the readOptionsMask argument, the NSData will read the contents of the file using an internally defined default configuration. That default configuration may change over time.
回答3:
This question is super old, but in case anyone finds it, the Objective-C version of the PHP code (assuming this is inside a class) would probably be something like this:
-(id)myFunction:(NSArray*)array {
return [self myFunction:array withSort:FALSE];
}
-(id)myFunction:(NSArray*)array withSort:(BOOL)useSort {
// CODE
}
I used (id)s as there is no data type information in your PHP code. Replacing the (id)s with actual data types would be wise.
回答4:
Terrible necro but for anyone googling this, Xcode 4.5 supports (via Clang) overloading of C functions with __attribute__((overloadable))
.
Overloaded functions are allowed to have different numbers of arguments, so if C functions are appropriate for what you're trying to do you can use that to get default argument values.
Here's a contrived example of an .h file with two functions, both called 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);
and in the .m file:
__attribute__((overloadable))
void PrintNum(NSNumber *number) {
PrintNum(number, 10);
}
__attribute__((overloadable))
void PrintNum(NSNumber *number, NSUInteger base) {
// ...
}
Note that the attribute must be specified in all definitions and declarations of the function.
回答5:
No, default arguments are a feature of C++, not C or Objective-C.
What you would have to do in objective-c is the following (using your psuedo code above):
function myFunction ($array, $sort)
function myFunction ($array)
// call myFunction($array, FALSE)
回答6:
You can easily achieve the same effect using #define
.
The function in your header file:
+(NSDate*)getDateFromYear:(NSUInteger)year month:(NSUInteger)month day:(NSUInteger)day;
Add a #define
for parameter function in header file:
#define GetDateFromYearOnly(year) [YourClassName getDateFromYear:year month:1 day:1]
Then your can use the function like:
NSDate* 2015Date = GetDateFromYearOnly(2015);
And you will get an NSDate
object with date 2015/01/01.
If the function is not static
, build a new function like this:
-(NSDate*)GetDateFromYearOnly:(NSUInteger)year;
And call:
[self getDateFromYear:year month:1 day:1]