2011-10-03 5 views
6

यह समझने के मेरे प्रयासों में कि मैं (उद्देश्य-) सी में va_list के साथ क्या कर सकता हूं और नहीं कर सकता, मैं इस छोटी पहेली में आया। मैं NSString पर एक श्रेणी बनाने की उम्मीद कर रहा था जो कुछ मामलों में stringWithFormat: संदेश को थोड़ा सा सरल बना देगा, बस इसके मजाक के लिए। एक स्ट्रिंग "My super format rocks!" कह के साथ समाप्त करने के लिए आशाक्या मैं इसे पास करने से पहले एक va_list संशोधित कर सकता हूं?

[@"My %@ format %@!" formattedWith:@"super", @"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: संदेश पर क्या पारित किया गया है इसलिए गलत प्रकार का परिणाम प्रस्तुत करता है।

प्रश्न पर। को initWithFormat: संदेश में भेजने से पहले va_list को संशोधित करने के तरीके हैं, तो क्या मैं किसी भी तरह से पहली तर्क सूची में वापस स्थानांतरित कर सकता हूं?

मैं एक पुनरावृत्ति प्रक्रिया की तलाश नहीं कर रहा हूं जहां मैं स्वयं va_list के माध्यम से लूप करता हूं, मैं पूरी तरह से va_list की सीमाओं को समझना चाहता हूं। धन्यवाद!

+0

हो सकता है कि इस ब्लॉग पोस्ट उपयोगी है http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html –

उत्तर

4

va_listmodified 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