简体   繁体   English

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

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

i was wondering why my code not work as i suppose to. 我想知道为什么我的代码无法按我预期的那样工作。 Please consider the following code: 请考虑以下代码:

- (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]];
}

Pretty straightforward. 非常简单。 Now, output result in console is (that is what orderString contain): 现在,控制台中的输出结果是(即orderString包含的内容):

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

Look like for some reason, we got only last word from text contained in bake NSString . 看起来由于某种原因,我们只能从bake NSString包含的文本中得到最后一个单词。 And compiler even warn this line of code with 2 "yellow" warnings: 编译器甚至用2个“黄色”警告来警告这一行代码:

Format string is not a string literal (potentially insecure) 格式字符串不是字符串文字(可能不安全)

Expression result unused 表达结果未使用

I solve that problem simply by remove round brackets like that: 我只需删除像这样的圆括号即可解决该问题:

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]];

However, i don't understand, why compiler truncate my string when i simply put statement in round brackets? 但是,我不明白,当我只是将语句放在圆括号中时,为什么编译器会截断我的字符串?

The parentheses (not round brackets) group everything inside it into an expression. 括号(不是圆括号)将其中的所有内容组合为一个表达式。 It useful to change the precedence of certain operators or to make code more readable. 更改某些运算符的优先级或使代码更具可读性很有用。

In C based languages (including Objective-C), the value of a series of comma separated expressions is the value of the last expression in the list. 在基于C的语言(包括Objective-C)中,一系列用逗号分隔的表达式的值是列表中最后一个表达式的值。

The parentheses in your line end up grouping the separate parameters to the stringWithFormat: method into a single argument instead of the expected separate set of arguments. 您行中的括号最终将stringWithFormat:方法的单独参数分组为单个参数,而不是预期的单独参数集。

So the value of: 因此,值:

(@"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])

is just the value of the last one: 只是最后一个的值:

[self sauce]

So in affect, your line is really just: 因此,在情感上,您的行实际上就是:

return [NSString stringWithFormat:[self sauce]];

which is why you get the two warnings and why it only returns Tobasko . 这就是为什么您会收到两个警告以及为什么只返回Tobasko

Further, the use of NSString stringWithFormat: should always have at least two parameters. 此外,使用NSString stringWithFormat:应该始终至少具有两个参数。 The first should be a string with at least one format specifier and the remaining parameters should correspond to each of the format specifiers in the format string. 第一个应该是带有至少一个格式说明符的字符串,其余参数应对应于格式字符串中的每个格式说明符。

So code like: 所以代码像:

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

Has two problems. 有两个问题。 1. Pointless parentheses and 2. There's no need to use stringWithFormat: . 1.无意义的括号和2.无需使用stringWithFormat: Just use: 只需使用:

return @"Cut in 4 pieces";

I think to understand what is happening, we need to break it down into 3 aspects: 我认为要了解正在发生的事情,我们需要将其分解为三个方面:

  1. [NSString stringWithFormat:] takes 1 or more arguments. [NSString stringWithFormat:] 1个或多个参数。 You can pass in just a string, with no other arguments, and it will return just that string. 您可以只传入一个字符串,没有其他参数,它将仅返回该字符串。 If you have format descriptors in the string (eg %@ , %d , etc.) then a matching number of additional parameters are required. 如果字符串中有格式描述符(例如%@%d等),则需要匹配数量的附加参数。 But again, a single string with no format descriptors is a valid parameter. 但是同样,没有格式描述符的单个字符串是有效参数。

  2. The parentheses () signify that the contents inside the parentheses should first be evaluated and then used as a single expression 括号()表示应先对括号内的内容求值,然后将其用作单个表达式

  3. The comma operator in C means, roughly, "evaluate these expressions from left to right and return the value of the rightmost expression" C中的逗号运算符大致意味着“从左到右评估这些表达式并返回最右边的表达式的值”

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

So what is happening in your "bake" method is: 因此,您的“烘烤”方法中发生的是:

  1. Evaluate the contents of the parentheses first as a single expression 首先以单个表达式评估括号的内容
  2. Since the contents of the parentheses are comma-separated, evaluate each expression left to right, and return the value of the rightmost expression (in this case [self sauce] , which evaluates to @"Tabasko" ) 由于括号的内容以逗号分隔,因此请从左至右评估每个表达式,然后返回最右边的表达式的值(在这种情况下, [self sauce]结果为@"Tabasko"
  3. Use this single expression as the parameter for [NSString stringWithFormat:] , ie [NSString stringWithFormat:@"Tabasko"]; 使用此单个表达式作为[NSString stringWithFormat:]的参数,即[NSString stringWithFormat:@"Tabasko"];

All of your other methods before "orderString" are just single string parameters anyway, so the parentheses don't make a difference in the final result. 无论如何,“ orderString”之前的所有其他方法都只是单个字符串参数,因此括号不会对最终结果产生影响。

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

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