2011-10-27 40 views
7

Tôi đang cố tạo danh sách đối số biến "giả", sử dụng kỹ thuật được mô tả here, nhưng đối với dự án có hỗ trợ ARC và tôi không thể tìm ra cách để loại bỏ lỗi tôi nhận được.Cách chuyển đổi từ char * sang id * bằng ARC bật

Dưới đây là mã trong câu hỏi:

NSMutableArray* argumentsArray = [NSMutableArray array]; 

// ... Here I fill argumentsArray with some elements 
// And then, I want to construct a "fake" variable argument list 

char* fakeArgList = (char*) malloc(sizeof(NSString*) * [argumentsArray count]); 
[argumentsArray getObjects: (id*) fakeArgList]; 

NSString* content = [[NSString alloc] initWithFormat: formatString arguments:fakeArgList]; 

XCode phàn nàn trên (id) fakeArgList * đúc, nói:

Cast của phi Objective-C kiểu con trỏ 'char * 'to' _ id tự động điền * ' không được phép với ARC

Lý thuyết ban đầu của tôi là thứ tôi chỉ cần thêm __unsafe_unretained vào (id *) casting để cho ARC biết rằng tôi chịu trách nhiệm về khối bộ nhớ đó và nó không nên giữ lại/giải phóng nó, nhưng điều đó không hiệu quả và tôi không thể tìm ra cách để khắc phục sự cố này.

Cập nhật: Đây là chức năng đầy đủ. Nó sẽ lấy một chuỗi định dạng kiểu printf và một danh sách biến các tên trường bên trong .plist và xuất ra một chuỗi được định dạng với dữ liệu được tải từ .plist. Ví dụ, nếu tôi có một file plist với các lĩnh vực "field1" = "foo" và "field2" = 3 và tôi gọi [loadStringFromFixture: @"?param1=%@&param2=%d", @"field1", @field2] sau đó tôi sẽ nhận được chuỗi "? Param1 = foo & param2 = 3"

- (NSString*) loadStringFromFixture:(NSString*) format, ... 
{ 
    NSString* path = [[NSBundle mainBundle] bundlePath]; 
    NSString* finalPath = [path stringByAppendingPathComponent:@"MockAPI-Fixtures.plist"]; 
    NSDictionary* plistData = [NSDictionary dictionaryWithContentsOfFile:finalPath]; 

    va_list argumentsList;  
    va_start(argumentsList, format); 

    NSString* nextArgument; 
    NSMutableArray* argumentsArray = [NSMutableArray array]; 

    while((nextArgument = va_arg(argumentsList, NSString*))) 
    { 
     [argumentsArray addObject: [plistData objectForKey:nextArgument]]; 
    } 

    NSRange myRange = NSMakeRange(0, [argumentsArray count]); 

    id* fakeArgList = (__bridge id *)malloc(sizeof(NSString *) * [argumentsArray count]); 
    [argumentsArray getObjects:fakeArgList range:myRange]; 
    NSString * content = [[NSString alloc] initWithFormat:formatString 
               arguments:(__bridge va_list)fakeArgList]; 

    free(fakeArgList); 

    return content; 
} 
+0

Có phải là một cách tốt hơn để làm điều này ... – semisight

+3

Nghiêm túc; một đọc nhanh của bài viết nguồn lá tôi nghĩ rằng nó chỉ hoạt động bằng sự trùng hợp ngẫu nhiên và nằm ngoài giới hạn của ABI hoặc spec. – bbum

+0

Đó là sự thật, nhưng tôi chỉ cần nó cho mã kiểm tra đơn vị của tôi, vì vậy tôi ít quan tâm đến thực tế rằng nó là một "hack khá" bẩn. Mặc dù nếu ai đó có thể chỉ ra một cách tốt hơn để xây dựng một danh sách các đối số biến, tôi thực sự quan tâm. –

Trả lời

1

Nhìn vào mã này, nó có vẻ như một hack khá bẩn, nhưng tôi cho rằng nếu nó hoạt động mà không có ARC, nó cũng sẽ làm việc với ARC. Vấn đề ở đây là bạn đang truyền từ C-con trỏ để trỏ Objective-C, mà bạn không thể làm mà không có cầu nối:

NSMutableArray * argumentsArray = [NSMutableArray array]; 

// ... Here I fill argumentsArray with some elements 
// And then, I want to construct a "fake" variable argument list 

NSRange myRange = NSMakeRange(0, [argumentsArray count]); 
id * fakeArgList = (__bridge id *)malloc(sizeof(NSString *) * [argumentsArray count]); 
[argumentsArray getObjects:fakeArgList range:myRange]; 
NSString * content = [[NSString alloc] initWithFormat:formatString 
              arguments:(__bridge va_list)fakeArgList]; 
free(fakeArgList); 

này vẫn còn khá xấu xí, và tôi thực sự hy vọng rằng có một cách tốt hơn làm điều này, nhưng vì nó là cho một bài kiểm tra đơn vị, tôi đoán nó sẽ phải làm.

EDIT: Nó có thể được rằng các diễn viên bắc cầu nên được thực hiện như thay vì điều này:

id __autoreleasing * fakeArgList = (__bridge id __autoreleasing *)malloc(sizeof(NSString *) * [argumentsArray count]); 
+0

Vẫn gặp lỗi trình biên dịch với mã đó. Nó phàn nàn về "các kiểu không tương thích truyền" void * "thành" __autoreleasing id * "với một __bridge cast" trên dòng với malloc. –

+0

Tôi đã cập nhật bài đăng gốc của mình với toàn bộ văn bản chức năng –

+0

Chỉnh sửa của tôi có thể là giải pháp của bạn hoặc có thể hoàn toàn bị tắt. Kiểm tra nó ra và xem. –

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