[英]ARC and varargs causes BAD_ACCESS
我正在查看一個可變參數列表,當我到達列表中的最后一個對象時,總是會收到BAD_ACCESS
錯誤。 我強烈認為這是與ARC相關的問題。
這是我的工作:
-(NSString *)replaceTokensWithStrings:(NSString *)firstKey, ... {
va_list _arguments;
va_start(_arguments, firstKey);
for (NSString *_currentArgument = firstKey; _currentArgument != nil; _currentArgument = va_arg(_arguments, NSString*)) {
NSLog(@"%@", _currentArgument);
}
va_end(_arguments);
return nil;
}
我必須以某種方式告訴編譯器保留va_arg
返回的結果,但我似乎無法弄清楚在何處以及如何應用此范例。
更新1:這就是我調用方法的方式:
[@"Hello <firstname> <lastname>" replaceTokensWithStrings:
@"firstname", @"Peter",
@"lastname", "Smith",
nil];
更新2:我更新了我的問題,並添加了一個錯誤,以表明我實際上做錯了什么。 請參閱下面的答案。
我徹底走錯了路。 問題根本不是函數,而是我如何調用該函數(其他參與者可能不知道這一點,因為我沒有在問題中的示例中出錯)。
我已經更新了我的問題,實際的問題是我沒有傳遞一個NSString列表,而是5個NSString, 最后一個是普通的C字符串。
最后一個C字符串導致BAD_ACCESS
:
壞:
"Smith"
好:
@"Smith"
現在我很尷尬:-)
每當C中有一個可變參數列表時,您都需要以某種方式指定列表中的項目數或標識最后一個項目-語言不會為您完成此操作。 這可以通過format語句-args數量與format項的數量匹配-或其他方案。 默認方案是使用nil
或NULL
結束調用語句中的參數列表。
如果您查看諸如NSArray arrayWithObjects
類的定義,則列表必須始終以nil
結尾。
我也在使用ARC
,正在使用以下模式,它對我來說很好用,我從未遇到過任何問題,它可能會對您有所幫助:
- (void)workingWithDictionaries:(NSDictionary *)dictionary, ... {
va_list _arguments;
va_start(_arguments, dictionary);
for (NSDictionary *_currentArgument = dictionary; _currentArgument != nil; _currentArgument = va_arg(_arguments, NSDictionary*)) {
NSLog(@"%@", _currentArgument);
}
va_end(_arguments);
}
我今天也遇到了同樣的問題,可以從技術上告訴您與ARC或保留無關,但是您的方法聲明/原型應該是
-(NSString *)replaceTokensWithStrings:(NSString *)firstKey, ...
NS_REQUIRES_NIL_TERMINATION;
這樣,您告訴Xcode和C預處理程序使用MACRO,並總是要求以'nil'結尾,因此它將阻止va_arg()訪問錯誤的位置(BAD_ACCESS)
它與ARC無關。 va_arg不會檢查它是否到達列表的末尾,因此將返回一個指向列表之后的內存塊的指針,該指針可以是任何東西。 因此,EXC_BAD_ACCESS。 通常,您將參數數量作為額外參數,例如:
-(void *)replaceTokensWithNumberOfStrings:(int)numStrings strings:(NSString *)str1, ... {
然后在while
循環中使用numStrings
。
如果期望va_arg返回的ID類型(在此示例中為NSString *),並且它返回nil值,則會發生崩潰。 這是因為arc試圖保留返回的nil。
為了避免這種情況,請在要分配的變量中添加__unsafe_unretained。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.