簡體   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