2011-10-27 5 views
7

here에 설명 된 기술을 사용하여 "위조 된"가변 인수 목록을 구성하려고하지만 ARC 사용 가능 프로젝트의 경우 얻을 방법을 알 수 없습니다. 내가 겪고있는 오류를 없애라.ARC를 사용하여 char *를 id *로 변환하는 방법

비 오브젝티브 C 포인터 타입 '문자의 캐스트 * : 말,

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]; 

엑스 코드는 (ID) fakeArgList * 캐스팅에 불만 : 여기

문제의 코드입니다 'to'_autoreleasing id * ' 은 ARC에서 허용되지 않습니다

제 초기 이론은 th (ID *) 캐스팅에 __unsafe_unretained를 추가하여 ARC에 메모리 블록을 담당하고 유지/릴리스해서는 안된다는 사실을 알리고 싶습니다.하지만 작동하지 않습니다. 이 문제를 해결하십시오.

업데이트 : 다음은 전체 기능입니다. 그것은 .plist 안에 printf-style 포맷 스트링과 필드 이름의 변수리스트를 가져 와서 .plist로부터로드 된 데이터로 포맷 된 스트링을 출력해야한다. 즉, 나는 필드 "필드 1"= "foo는"과 "FIELD2"= 3, 그때 내가 문자열을 얻어야한다 [loadStringFromFixture: @"?param1=%@&param2=%d", @"field1", @field2] 전화? "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

이 할 수있는 더 좋은 방법이 있어야합니다 ... – semisight

+3

진심; 원본 기사를 빨리 읽으면 우연히 만 작동하고 ABI 또는 사양 범위를 벗어난다고 생각합니다. – bbum

+0

사실,하지만 내 단위 테스트 코드에만 필요하기 때문에 꽤 더러운 해킹이라는 사실에 덜 관심이 있습니다. 누군가 가변 인수 목록을 만드는 더 좋은 방법을 지적 할 수는 있지만, 나는 정말로 흥미 롭다. –

답변

1

와 .plist 파일이있는 경우 이 코드를 보면 상당히 더러운 해킹처럼 보이지만 ARC없이 작동하는 경우 ARC를 사용해야한다고 가정합니다. 여기서 문제는 해소하지 않고는 할 수없는 목표 - C 포인터에 C-포인터로 캐스팅하고 있다는 것입니다 :

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); 

이 여전히 매우 추한이고, 난 정말 더 나은 방법이 있기를 바랍니다 이것을하는 것이지만 단위 테스트를위한 것이기 때문에해야 할 것입니다.

편집 : 그것은 브리지 캐스트가 대신이 같은 수행해야 할 수 있음 :

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

해당 코드로 컴파일러 오류가 발생했습니다. malloc을 사용하여 "void *"를 "__bridge cast와 함께"__autoreleasing id *로 캐스팅하는 호환되지 않는 유형에 대해 불평합니다. –

+0

전체 기능 텍스트로 원래 게시물을 업데이트했습니다. –

+0

내 편집이 해결책이 될 수도 있고 완전히 해제되었을 수도 있습니다. 그것을 확인하고 참조하십시오. –

관련 문제