2009-07-30 37 views
7

Giả sử tôi có một phương pháp với chữ ký:Cách thích hợp để bao bọc [NSString stringWithFormat:] là gì?

+ (NSString *) myFormattedString:(NSString *)format, ...; 

Và tôi muốn nó thêm vào trước một chuỗi các lựa chọn của tôi (ví dụ: @ "Foo:"). Tôi đoán cách tốt nhất là sử dụng [myString initWithFormat: arguments:], nhưng làm thế nào bạn sẽ thực hiện phương pháp này?


tôi đã cố gắng làm như sau, nhưng tôi nhận được cảnh báo theo quy định tại các comment:

+ (NSString *) myFormattedString:(NSString *)format, ... { 
    char *buffer; 
    [format getCString:buffer maxLength:[format length] encoding:NSASCIIStringEncoding]; 

    va_list args; 
    va_start(args, buffer); // WARNING: second parameter of 'va_start' not last named argument 

    NSString *str = [[NSString alloc] initWithFormat:format arguments:args]; 
    [str autorelease]; 

    return [NSString stringWithFormat:@"Foo: %@.", str]; 
} 

Lý do tôi giả va_start() có thể mất trong một (char *) là vì ví dụ tôi thấy trên manual page of STDARG(3). Cảm thấy tự do để viết lại hoàn toàn phương pháp nếu tôi làm điều đó hoàn toàn sai.

Trả lời

15

Tôi nghĩ rằng những gì bạn muốn là một cái gì đó như:

+ (NSString *) myFormattedString:(NSString *)format, ... { 
    va_list args; 
    va_start(args, format); 
    NSString *str = [[[NSString alloc] initWithFormat:format arguments:args] autorelease]; 
    va_end(args); 
    return [NSString stringWithFormat:@"Foo: %@.", str]; 
} 

Các stdarg.hva_ * macro được sử dụng khi một chức năng (hoặc, trong trường hợp này, phương pháp) có một số biến của tham số, theo quy định của " ... ". va_start() được sử dụng để tìm sự bắt đầu của nơi mà số đối số biến bắt đầu. Như vậy, nó cần phải biết một hàm/phương thức đối số cuối cùng (đối số ngay trước "...") để xác định nơi bắt đầu số đối số biến. Đây là một lời giải thích đơn giản vì những gì thực sự xảy ra dưới mui xe là rất cụ thể ABI/Compiler. Điểm quan trọng nhất là đối số thứ hai cho va_start() luôn là tên của biến 'ngay trước "..."'.

va_end() phải được "gọi" (nó thực sự là macro, không phải chức năng) cho tính di động tối đa. Một lần nữa, toàn bộ biến đối số biến này là ma thuật đen sâu, sâu sắc. Tùy thuộc vào các chi tiết cụ thể của trình biên dịch và ABI, va_end() có thể không làm gì cả. Mặt khác, việc không sử dụng va_end() có thể khiến chương trình của bạn gặp sự cố khi tuyên bố return đạt được vì khung ngăn xếp (nếu có) không còn được thiết lập đúng để thực sự trả lại.

+0

Woops, tôi hiểu lầm cách va_start() hoạt động. Tôi đoán http://numbergrinder.com/node/35 không giải thích rõ ràng. Tôi nghĩ tham số thứ hai là va_start() là số đếm thực tế về số lượng param được gửi đến hàm; và rằng nó có một 'quá tải' trong chuỗi định dạng xác định số lượng dựa trên số lượng không thoát của% đã có trong chuỗi định dạng ... Wow giúp bạn dễ dàng hơn để xác định tự tính. Cảm ơn lời giải thích. – Senseful

8

Bạn gần như đã có nó; chỉ cần một vài điều chỉnh:

+ (NSString *) myFormattedString:(NSString *)format, ... { 
    va_list args; 
    va_start(args, format); 

    NSString *str = [[NSString alloc] initWithFormat:format arguments:args]; 
    [str autorelease]; 

    va_end(args); 

    return [NSString stringWithFormat:@"Foo: %@.", str]; 
} 

Điều đó sẽ làm những gì bạn đang tìm kiếm.

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