Objective c 在不传递nil的情况下迭代函数中可变数量的参数

Objective c 在不传递nil的情况下迭代函数中可变数量的参数,objective-c,c,Objective C,C,一、 像许多人一样,必须经常查找日期格式化程序的日期代码。我决定制作一个文件,让我更容易记住它们。我包括一个可读性函数,我声明如下: NSString * dateFormatString(NSString * string1, ...) { // Parse out Args va_list args; va_start(args,string1); // Set up our Format String NSMutableString * form

一、 像许多人一样,必须经常查找日期格式化程序的日期代码。我决定制作一个文件,让我更容易记住它们。我包括一个可读性函数,我声明如下:

NSString * dateFormatString(NSString * string1, ...) {

    // Parse out Args
    va_list args;
    va_start(args,string1);

    // Set up our Format String
    NSMutableString * formatString = [NSMutableString string];

    // Build Format string
    for (NSString * arg = string1; arg != nil; arg = va_arg(args, NSString*)) {
        [formatString appendString:arg];
    }

    va_end(args);

    return formatString;
}
dateFormatter.dateFormatString = dateFormatString(DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete, nil);
NSString * dateFormatterString = dateFormatString(DKDayOfWeekAbbreviated, @", ", DKMonthNameAbbreviated, @" ", DKDayOfMonthComplete, @" ", DKYearComplete, @"'at' ", DKHour12hrComplete, @":", DKMinutes2Digits, @" ", DKAmPm, nil);
dateFormatter.dateFormatString = dateFormatString(@[ DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete ]);
#define DKDayOfWeekAbbreviated @"E"
#define DKDayOfWeekFull @"EEEE"
#define DKMonthNameFull @"MMMM"
#define DKDayOfMonthComplete @"dd"
因此,我可以这样编写我的
NSDateFormatter

NSString * dateFormatString(NSString * string1, ...) {

    // Parse out Args
    va_list args;
    va_start(args,string1);

    // Set up our Format String
    NSMutableString * formatString = [NSMutableString string];

    // Build Format string
    for (NSString * arg = string1; arg != nil; arg = va_arg(args, NSString*)) {
        [formatString appendString:arg];
    }

    va_end(args);

    return formatString;
}
dateFormatter.dateFormatString = dateFormatString(DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete, nil);
NSString * dateFormatterString = dateFormatString(DKDayOfWeekAbbreviated, @", ", DKMonthNameAbbreviated, @" ", DKDayOfMonthComplete, @" ", DKYearComplete, @"'at' ", DKHour12hrComplete, @":", DKMinutes2Digits, @" ", DKAmPm, nil);
dateFormatter.dateFormatString = dateFormatString(@[ DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete ]);
#define DKDayOfWeekAbbreviated @"E"
#define DKDayOfWeekFull @"EEEE"
#define DKMonthNameFull @"MMMM"
#define DKDayOfMonthComplete @"dd"
您可以通过声明实现几乎相同的目标:

[NSString stringWithFormat:@"%@, %@ %@", DKDayOfWeekFull, DKMonthNameFull, DKDayOfMonthComplete];
然而,如果你用更多变量来描述一个日期,比如“Sat,2006年1月14日上午7:52”,那么它必须是:

 NSString * dateFormatterString = [NSString stringWithFormat:@"%@, %@ %@ %@ 'at' %@:%@ %@", DKDayOfWeekAbbreviated, DKMonthNameAbbreviated, DKDayOfMonthComplete, DKYearComplete, DKHour12hrComplete, DKMinutes2Digits, DKAmPm];
我个人认为这样更具可读性:

NSString * dateFormatString(NSString * string1, ...) {

    // Parse out Args
    va_list args;
    va_start(args,string1);

    // Set up our Format String
    NSMutableString * formatString = [NSMutableString string];

    // Build Format string
    for (NSString * arg = string1; arg != nil; arg = va_arg(args, NSString*)) {
        [formatString appendString:arg];
    }

    va_end(args);

    return formatString;
}
dateFormatter.dateFormatString = dateFormatString(DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete, nil);
NSString * dateFormatterString = dateFormatString(DKDayOfWeekAbbreviated, @", ", DKMonthNameAbbreviated, @" ", DKDayOfMonthComplete, @" ", DKYearComplete, @"'at' ", DKHour12hrComplete, @":", DKMinutes2Digits, @" ", DKAmPm, nil);
dateFormatter.dateFormatString = dateFormatString(@[ DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete ]);
#define DKDayOfWeekAbbreviated @"E"
#define DKDayOfWeekFull @"EEEE"
#define DKMonthNameFull @"MMMM"
#define DKDayOfMonthComplete @"dd"
问题: 我更喜欢一种迭代变量的方法,而不必将nil传递到函数中。除了以下方法外,是否还有其他方法可以迭代变量参数列表:

for (NSString * arg = string1; arg != nil; arg = va_arg(args, NSString*)) {
    [formatString appendString:arg];
}

使用标准C语法支持变量参数的唯一方法是执行您正在执行的操作

但是您还有另一个选择-使用
NSArray

您的功能变为:

NSString * dateFormatString(NSArray *strings) {
    // Set up our Format String
    NSMutableString * formatString = [NSMutableString string];

    // Build Format string
    for (NSString * arg in strings) {
        [formatString appendString:arg];
    }

    return formatString;
}
或者干脆做:

NSString * dateFormatString(NSArray *strings) {
    return [strings componentsJoinedByString:@""];
}
你这样称呼它:

NSString * dateFormatString(NSString * string1, ...) {

    // Parse out Args
    va_list args;
    va_start(args,string1);

    // Set up our Format String
    NSMutableString * formatString = [NSMutableString string];

    // Build Format string
    for (NSString * arg = string1; arg != nil; arg = va_arg(args, NSString*)) {
        [formatString appendString:arg];
    }

    va_end(args);

    return formatString;
}
dateFormatter.dateFormatString = dateFormatString(DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete, nil);
NSString * dateFormatterString = dateFormatString(DKDayOfWeekAbbreviated, @", ", DKMonthNameAbbreviated, @" ", DKDayOfMonthComplete, @" ", DKYearComplete, @"'at' ", DKHour12hrComplete, @":", DKMinutes2Digits, @" ", DKAmPm, nil);
dateFormatter.dateFormatString = dateFormatString(@[ DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete ]);
#define DKDayOfWeekAbbreviated @"E"
#define DKDayOfWeekFull @"EEEE"
#define DKMonthNameFull @"MMMM"
#define DKDayOfMonthComplete @"dd"

不需要使用现代的
NSArray
语法
nil

使用标准C语法支持变量参数的唯一方法是执行您正在执行的操作

但是您还有另一个选择-使用
NSArray

您的功能变为:

NSString * dateFormatString(NSArray *strings) {
    // Set up our Format String
    NSMutableString * formatString = [NSMutableString string];

    // Build Format string
    for (NSString * arg in strings) {
        [formatString appendString:arg];
    }

    return formatString;
}
或者干脆做:

NSString * dateFormatString(NSArray *strings) {
    return [strings componentsJoinedByString:@""];
}
你这样称呼它:

NSString * dateFormatString(NSString * string1, ...) {

    // Parse out Args
    va_list args;
    va_start(args,string1);

    // Set up our Format String
    NSMutableString * formatString = [NSMutableString string];

    // Build Format string
    for (NSString * arg = string1; arg != nil; arg = va_arg(args, NSString*)) {
        [formatString appendString:arg];
    }

    va_end(args);

    return formatString;
}
dateFormatter.dateFormatString = dateFormatString(DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete, nil);
NSString * dateFormatterString = dateFormatString(DKDayOfWeekAbbreviated, @", ", DKMonthNameAbbreviated, @" ", DKDayOfMonthComplete, @" ", DKYearComplete, @"'at' ", DKHour12hrComplete, @":", DKMinutes2Digits, @" ", DKAmPm, nil);
dateFormatter.dateFormatString = dateFormatString(@[ DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete ]);
#define DKDayOfWeekAbbreviated @"E"
#define DKDayOfWeekFull @"EEEE"
#define DKMonthNameFull @"MMMM"
#define DKDayOfMonthComplete @"dd"

不需要使用现代的
NSArray
语法
nil

我假定您的意思是说
dateFormatter.dateFormat=…
,因为
NSDateFormatter
没有
dateFormatter字符串
属性

我假设
dkdayofweekabbreeviated
是一个字符串常量,定义为
@“E”
DKDayOfWeekFull
@“EEEE”
,依此类推

如果是这样,这里有一个不同的方法。按如下方式定义常量:

NSString * dateFormatString(NSString * string1, ...) {

    // Parse out Args
    va_list args;
    va_start(args,string1);

    // Set up our Format String
    NSMutableString * formatString = [NSMutableString string];

    // Build Format string
    for (NSString * arg = string1; arg != nil; arg = va_arg(args, NSString*)) {
        [formatString appendString:arg];
    }

    va_end(args);

    return formatString;
}
dateFormatter.dateFormatString = dateFormatString(DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete, nil);
NSString * dateFormatterString = dateFormatString(DKDayOfWeekAbbreviated, @", ", DKMonthNameAbbreviated, @" ", DKDayOfMonthComplete, @" ", DKYearComplete, @"'at' ", DKHour12hrComplete, @":", DKMinutes2Digits, @" ", DKAmPm, nil);
dateFormatter.dateFormatString = dateFormatString(@[ DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete ]);
#define DKDayOfWeekAbbreviated @"E"
#define DKDayOfWeekFull @"EEEE"
#define DKMonthNameFull @"MMMM"
#define DKDayOfMonthComplete @"dd"
然后使用编译时字符串连接来构建字符串。编译器合并两个相邻的字符串常量。例如,
“hello”“world”
变成
“hello world”
@“hello”@“world”
变成
@“hello world”
。事实上,您可以省略第二个和以后的
@
字符,因此
@“hello”“world”
变成
@“hello world”

因此:


您不需要helper函数或varargs。

我想您的意思是说
dateFormatter.dateFormat=…
,因为
NSDateFormatter
没有
DateFormattString
属性

我假设
dkdayofweekabbreeviated
是一个字符串常量,定义为
@“E”
DKDayOfWeekFull
@“EEEE”
,依此类推

如果是这样,这里有一个不同的方法。按如下方式定义常量:

NSString * dateFormatString(NSString * string1, ...) {

    // Parse out Args
    va_list args;
    va_start(args,string1);

    // Set up our Format String
    NSMutableString * formatString = [NSMutableString string];

    // Build Format string
    for (NSString * arg = string1; arg != nil; arg = va_arg(args, NSString*)) {
        [formatString appendString:arg];
    }

    va_end(args);

    return formatString;
}
dateFormatter.dateFormatString = dateFormatString(DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete, nil);
NSString * dateFormatterString = dateFormatString(DKDayOfWeekAbbreviated, @", ", DKMonthNameAbbreviated, @" ", DKDayOfMonthComplete, @" ", DKYearComplete, @"'at' ", DKHour12hrComplete, @":", DKMinutes2Digits, @" ", DKAmPm, nil);
dateFormatter.dateFormatString = dateFormatString(@[ DKDayOfWeekFull, @", ", DKMonthNameFull, @" ", DKDayOfMonthComplete ]);
#define DKDayOfWeekAbbreviated @"E"
#define DKDayOfWeekFull @"EEEE"
#define DKMonthNameFull @"MMMM"
#define DKDayOfMonthComplete @"dd"
然后使用编译时字符串连接来构建字符串。编译器合并两个相邻的字符串常量。例如,
“hello”“world”
变成
“hello world”
@“hello”@“world”
变成
@“hello world”
。事实上,您可以省略第二个和以后的
@
字符,因此
@“hello”“world”
变成
@“hello world”

因此:



您不需要helper函数或varargs。

谢谢@rmaddy,你知道NSString和NSLog是如何解决的吗?这是个好问题,因为许多其他方法确实需要
nil
终止符。我唯一能想到的是,它们解析格式字符串并计算
%
的实例,以知道要迭代多少个参数。这比只计算
%
字符要复杂一些,但是,是的,格式字符串指示后面有多少个参数,因此不需要在末尾使用nil。示例:
%*.*s
使用三个参数
%%
不使用任何参数。更简洁地说:
[字符串组件由字符串连接:@”“]
谢谢@rmaddy,你知道NSString和NSLog是如何解决的吗?这是个好问题,因为许多其他方法确实需要
nil
终止符。我唯一能想到的是,它们解析格式字符串并计算
%
的实例,以知道要迭代多少个参数。这比只计算
%
字符要复杂一些,但是,是的,格式字符串指示后面有多少个参数,因此不需要在末尾使用nil。示例:
%*.*s
使用三个参数<代码>%%不使用任何参数。更简洁地说:
[strings componentsJoinedByString:@”“]
Slick。我总是忘记你可以用这种方式附加字符串常量。这很酷!我不知道你能做到。绝对值得投一票!我有两个问题,这导致。1.我不会让自动填充超过第一个变量。2.我目前使用
/*在我的密钥中声明了描述!description*/
这样我就可以在搜索时看到每个键的作用。我总是忘记你可以用这种方式附加字符串常量。这很酷!我不知道你能做到。绝对值得投一票!我有两个问题,这导致。1.我不会让自动填充超过第一个变量。2.我目前使用
/*在我的密钥中声明了描述!description*/
这样我就可以看到每个键在搜索时的作用。如果您这样声明函数,编译器会警告您忘记了
nil
NSString*dateFormatString(NSString*,…)NS\u需要nil\u终止@RobMayoff-太完美了!它把它填满了,所以人们不会忘记。谢谢如果您这样声明函数,编译器将警告您忘记了
nil
NSString*dateFormatString(NSString*,…)NS\u需要\u nil\u终止@RobMayoff-太完美了!它把它填满了,所以人们不会忘记。谢谢