2011-10-03 24 views
6

Trong nỗ lực của tôi để hiểu những gì tôi có thể và không thể làm với một va_list trong (Objective-) C, tôi đi qua câu đố nhỏ này. Tôi đã hy vọng tạo ra một loại trên NSString mà sẽ đơn giản hóa các thông báo stringWithFormat: một chút trong một số trường hợp, chỉ cho những niềm vui của nó. Những gì tôi đang nhắm đến là có thể sử dụng cách triển khai như sau:Tôi có thể sửa đổi danh sách va_list trước khi chuyển nó không?

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

Hy vọng kết thúc bằng một chuỗi có ghi "My super format rocks!". My (không chính xác) phương pháp thực hiện như sau:

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

Bây giờ vấn đề là càng sớm càng va_start() được gọi, va_list được 'rút ngắn' (vì thiếu một từ tốt hơn) và chỉ chứa các phần còn lại của đối số (trong trường hợp ví dụ chỉ còn lại @"rocks", cộng với đối tượng gọi mà tôi không quan tâm). Những gì được truyền vào thông báo initWithFormat: do đó kết xuất sai loại kết quả.

Đến câu hỏi. Có cách nào để sửa đổi va_list trước khi tôi chuyển nó tới thông báo initWithFormat:, vì vậy bằng cách nào đó tôi có thể chuyển đối số đầu tiên trở lại vào danh sách?

Tôi không tìm kiếm một quy trình lặp đi lặp lại nơi tôi tự mình xem qua va_list, tôi đang tìm hiểu các giới hạn của va_list nói chung. Cảm ơn!

+0

Có thể bài đăng trên blog này hữu ích http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html –

Trả lời

4

va_list không được là modified safely. Đối số va_start cũng yêu cầu đối số để bắt đầu danh sách bị loại trừ. Các cách để làm việc xung quanh điều này là hoặc là vượt qua một đối số vô dụng bổ sung hoặc sử dụng các macro variadic.

//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

Cảm ơn, câu trả lời rất rõ ràng! – epologee

Các vấn đề liên quan