繁体   English   中英

Objective-C中圆括号的奇怪行为

[英]Odd behaviour of round brackets in objective-c

我想知道为什么我的代码无法按我预期的那样工作。 请考虑以下代码:

- (NSString *)bake {
    return [NSString stringWithFormat:(@"Take %@, put it in oven for 30 minutes, add 250 gramm of %@ cheese, many %@ toppings and little drop of %@ sauce", [self dough], [self cheese], [self toppings], [self sauce])];
}

- (NSString *)cut {
    return [NSString stringWithFormat:(@"Cut in 4 pieces")];
}

- (NSString *)box {
    return [NSString stringWithFormat:(@"Box pizza. Ready for sale!")];
}

- (NSString *)orderString {
    return [NSString stringWithFormat:@"%@ %@ %@", [self bake], [self cut], [self box]];
}

非常简单。 现在,控制台中的输出结果是(即orderString包含的内容):

Tobasko Cut in 4 pieces Box pizza. Ready for sale!

看起来由于某种原因,我们只能从bake NSString包含的文本中得到最后一个单词。 编译器甚至用2个“黄色”警告来警告这一行代码:

格式字符串不是字符串文字(可能不安全)

表达结果未使用

我只需删除像这样的圆括号即可解决该问题:

return [NSString stringWithFormat:@"Take %@, put it in oven for 30 minutes, add 250 gramm of %@ cheese, many %@ toppings and little drop of %@ sauce", [self dough], [self cheese], [self toppings], [self sauce]];

但是,我不明白,当我只是将语句放在圆括号中时,为什么编译器会截断我的字符串?

括号(不是圆括号)将其中的所有内容组合为一个表达式。 更改某些运算符的优先级或使代码更具可读性很有用。

在基于C的语言(包括Objective-C)中,一系列用逗号分隔的表达式的值是列表中最后一个表达式的值。

您行中的括号最终将stringWithFormat:方法的单独参数分组为单个参数,而不是预期的单独参数集。

因此,值:

(@"Take %@, put it in oven for 30 minutes, add 250 gramm of %@ cheese, many %@ toppings and little drop of %@ sauce", [self dough], [self cheese], [self toppings], [self sauce])

只是最后一个的值:

[self sauce]

因此,在情感上,您的行实际上就是:

return [NSString stringWithFormat:[self sauce]];

这就是为什么您会收到两个警告以及为什么只返回Tobasko

此外,使用NSString stringWithFormat:应该始终至少具有两个参数。 第一个应该是带有至少一个格式说明符的字符串,其余参数应对应于格式字符串中的每个格式说明符。

所以代码像:

return [NSString stringWithFormat:(@"Cut in 4 pieces")];

有两个问题。 1.无意义的括号和2.无需使用stringWithFormat: 只需使用:

return @"Cut in 4 pieces";

我认为要了解正在发生的事情,我们需要将其分解为三个方面:

  1. [NSString stringWithFormat:] 1个或多个参数。 您可以只传入一个字符串,没有其他参数,它将仅返回该字符串。 如果字符串中有格式描述符(例如%@%d等),则需要匹配数量的附加参数。 但是同样,没有格式描述符的单个字符串是有效参数。

  2. 括号()表示应先对括号内的内容求值,然后将其用作单个表达式

  3. C中的逗号运算符大致意味着“从左到右评估这些表达式并返回最右边的表达式的值”

http://crasseux.com/books/ctutorial/The-comma-operator.html

因此,您的“烘烤”方法中发生的是:

  1. 首先以单个表达式评估括号的内容
  2. 由于括号的内容以逗号分隔,因此请从左至右评估每个表达式,然后返回最右边的表达式的值(在这种情况下, [self sauce]结果为@"Tabasko"
  3. 使用此单个表达式作为[NSString stringWithFormat:]的参数,即[NSString stringWithFormat:@"Tabasko"];

无论如何,“ orderString”之前的所有其他方法都只是单个字符串参数,因此括号不会对最终结果产生影响。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM