2012-02-15 3 views
4

일부 메소드가 반환되기 때문에 불행히도 누수가있는 것처럼 보이지만 해제하는 방법을 알아낼 수 없습니다. void* ' 할당 후, NSInvocation에서 반환했습니다.NSOperationQueue를 사용하여 반환 된 후 malloc'd void *를 반환 한 후

다음 구현에서는 다음 실행 루프에서 수행되는 블록으로 해제하려고했지만 returnBuffer이 할당되지 않아 충돌이 발생합니다.

블록에서 returnBuffer을 해제 할 수없는 이유는 무엇이며 할당되지 않은 이유는 무엇입니까? returnBuffer!=NULL을 통과하는 이유는 무엇입니까?

IMP 스윕과 관련이있는 특별한 방법이므로 메서드 반환 형식을 알 수 없습니다. NSData 또는 무엇인가 넣으면 작동하지 않습니다. 답변

NSUInteger length = [[invocation methodSignature] methodReturnLength]; 
if(length!=0){ 
    void* returnBuffer = (void *)malloc(length); 
    [invocation getReturnValue:&returnBuffer]; 
    if(returnBuffer!=NULL){ 
     void(^delayedFree)(void) = ^{ free(returnBuffer); }; 
     [[NSOperationQueue mainQueue] addOperationWithBlock:delayedFree]; 
    } 
    return returnBuffer; 
} 
return nil; 

는 당신은 void *NSMutableData에서, 당신이 malloc()에서 할 수처럼를 얻을 수 있습니다 조쉬의 -[NSMutableData mutableBytes] 트릭

NSUInteger length = [[invocation methodSignature] methodReturnLength]; 
if(length!=0){ 
    NSMutableData * dat = [[NSMutableData alloc] initWithLength:length]; 
    void* returnBuffer = [dat mutableBytes]; 
    [invocation getReturnValue:&returnBuffer]; 
    void(^delayedFree)(void) = ^{ [dat release]; }; 
    [[NSOperationQueue mainQueue] addOperationWithBlock:delayedFree]; 
    return returnBuffer; 
} 
return nil; 
+0

Dat release tho. – immibis

답변

2

에 다음과 같은 방법 덕분에 작업에 도착하고, 기본적으로 설정 그것을 인스턴스 변수에 넣으므로 할당의 수명은 인스턴스의 수명과 관련됩니다. 이 트릭을 Mike Ash에서 받았습니다. 나는 최근에 어떤 사람 NSInvocation 자신을 원숭이하고있다; 이 (당신은 물론, 방법에 대한 자신의 접두사를 사용한다) NSInvocation의 범주에 있습니다

static char allocations_key; 
- (void *) Wool_allocate: (size_t)size { 
    NSMutableArray * allocations = objc_getAssociatedObject(self, 
                  &allocations_key); 
    if(!allocations){ 
     allocations = [NSMutableArray array]; 
     objc_setAssociatedObject(self, &allocations_key, 
           allocations, OBJC_ASSOCIATION_RETAIN); 
    } 

    NSMutableData * dat = [NSMutableData dataWithLength: size]; 
    [allocations addObject:dat]; 

    return [dat mutableBytes]; 
} 

을 잘 모르겠어요 어디가 위치한 게시 한 코드; 자신 만의 커스텀 클래스에 있다면 관련 객체 비트를 처리 할 필요가 없습니다. 단지 allocations을 ivar로 만듭니다.

코드에이를 묶는 : 당신이 연관된 객체 경로를 사용하는 경우이 인스턴스가있는 경우

NSUInteger length = [[invocation methodSignature] methodReturnLength]; 
if(length!=0){ 
    void* returnBuffer = [self Wool_allocate:length]; 
    [invocation getReturnValue:&returnBuffer]; 
    return returnBuffer; 
} 
return nil; 

가의 allocations 배열이 해제됩니다. 그렇지 않으면 dealloc[allocations release]을 입력하면됩니다.

free() 또한 문제를 해결하기보다는 문제가 된 것으로 대답하려면 malloc()에서 가져 오지 않은 포인터에 대해서는 작동하지 않습니다. 포인터가 블록에서 사용될 때, 나는 꽤 복사 될 것이 확실하므로 또 다른 포인터 - 여전히 동일한 메모리를 가리키고 있지만 하나는 free()이 소유하고 있다고 생각하지 않는다. 따라서 할당하지 않은 것에 대한 오류가 발생합니다.

+0

고마워, 나는 당신의 구현을 따르지 않고 있지만 NSMutableData mutableBytes 트릭은 정확히 내가 한 것 같다. –

+0

도움이 되니 기쁩니다! 나는 당신이 원하는 것을 분명히하려고 노력할 수있다. –

+0

죄송합니다. 분명히해야합니다. 나는 당신의 구현을 "따르지"않는다. 나는 같은 방식으로 구현하지 않는다. 귀하의 구현에 대한 귀하의 대답은 매우 분명했습니다. –

관련 문제