2011-10-03 108 views
6

在我試圖理解我可以做什麼和不能做什麼(Objective-)C中的va_list時,我遇到了這個小小的難題。我希望在NSString上創建一個類別,以便在某些情況下簡化stringWithFormat:消息,僅僅爲了它的樂趣。我瞄準的是能夠使用實施這樣的:在傳遞之前可以修改va_list嗎?

[@"My %@ format %@!" formattedWith:@"super", @"rocks"]; 

希望能與一個字符串說「My super format rocks!」結束了。我(不正確)方法的實現看起來是這樣的:

- (NSString *)formattedWith:(NSString *)arguments, ... 
{ 
    va_list list; 
    va_start(list, arguments); 
    NSString *formatted = [[[NSString alloc] initWithFormat:self arguments:list] autorelease]; 
    va_end(list); 
    return formatted; 
} 

現在的問題是,一旦va_start()被調用時,va_list的是「縮短」(由於缺乏一個更好的詞),只包含的其餘參數(在僅有示例@"rocks"的情況下,加上我不關心的調用對象)。傳遞給initWithFormat:消息的內容因此呈現錯誤的結果類型。

對問題。有沒有方法修改 va_list之前,我把它傳遞給initWithFormat:消息,所以我可以以某種方式將第一個參數移回列表?

我不是在尋找一個迭代過程,我通過va_list自己循環,我期望瞭解va_list作爲一個整體的極限。謝謝!

+0

也許這篇博客是有幫助的http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html –

回答

4

va_list不能是modified safely。參數va_start還需要一個參數來啓動排除的列表。解決這個問題的方法是傳遞一個額外的無用參數或使用可變宏。

//Method declaration 
-(NSString*)formattedWith:(NSString*)ignored,...; 

//Opt 1 (pass anything for first value) 
[@"My %@ format %@!" formattedWith:nil, @"super", @"rocks"]; 

//Opt 2 (create a macro for the arguments) 
#define VA_OPT(...) nil, ##__VA_ARGS__ //VARIADIC OPTIONAL 
[@"My %@ format %@!" formattedWith:VA_OPT(@"super", @"rocks"]; 

//Opt 3 (just create a macro for the whole string format) 
//Obviously you should just use the NSString method directly before resorting to this 
#define FORMATTED_NSSTRING(str, ...) [NSString stringWithFormat:str, ##__VA_ARGS__] 
FORMATTED_NSSTRING(@"My %@ format %@!", @"super", @"rocks") 
+0

謝謝,非常明確的答案! – epologee

相關問題