2012-05-26 4 views
1

ARC (자동 참조 계산)를 사용하여 이상한 (내게 보이는) 상황과 간단한 메모리 누출 상황이 있습니다. 저는 iOS 코드로 작업하고 있습니다 만, 일반적으로 Objective-C에 적용해야한다고 생각합니다.매개 변수 개체를 반환 할 때 ARC가있는 메모리 누수가


나는 매개 변수 객체의 속성을 확인 후 매개 변수로 지정된 객체를 반환하는 다음과 같은 기능을 가지고있다.

- (id) returnParam:(id) obj 
{ 
    // Do whatever filtering needed. Return nil for invalid input. 

    return (NSNumber *)obj; 
} 

다음 I 루프에서이 방법을 호출하는 경우, I는, 할당 된 메모리는 루프 악기 만료 될 때까지 계속 증가 것을 알 수있다. 다음과 같이 내가 루프에서 returnParam 함수의 내용을 넣을 경우


for(int i = 0; i < 1000000; i++) 
{   
    id obj = [[NSNumber alloc] initWithInt:i];   
    id obj2 = [self returnParam:obj]; 
    NSLog(@"attempt %@", obj2); 
} 

그러나, 모든 것이 잘 작동합니다. 메모리 풋 스탬프는 모두 같은 크기로 유지됩니다.
for(int i = 0; i < 1000000; i++) 
{   
    id obj = [[NSNumber alloc] initWithInt:i]; 

    // Do whatever filtering needed. Break on invalid input. 

    id obj2 = obj; 

    NSLog(@"attempt %@", obj2); 
} 
I은 ​​필터링 부를 제거했다


은 (따라서 본질적 기능은 다시 호출자에게 객체를 전달), 동일한 상황이 지속. 이 순서는 생각으로 수를 유지 감소하지 않는 이유


이 이해하지, 나는 여기 저기, __weak__unsafe_unretained을 모든 가능한 조합을 시도했지만 아무도 일하지.

왜이 (매개 변수 객체 반환)이 작동하지 않는지 설명하고이 문제의 해결책을 제안 할 수 있습니까?


P. BTW, 악기에서 메모리 누수 이벤트로 캡처되지 않습니다,하지만 내가 생각하는 상황은 명백한 메모리 누수입니다.

답변

3

누출이 아닙니다. 그것은 -autorelease의 작동 방식과 관련이 있습니다. 무엇 -returnParam:에 확장은하지 : 따라서, 귀하의 변수는 다음 autorelasepool까지 정리되지 않아요

for (int i = 0; i < 1000; i++) 
{ 
    id obj = [[NSNumber numberWithInt:i] retain]; // retain, because 'obj' is strong by default. 
    id obj2 = [obj retain]; // retain, because 'obj2' is strong by default 

    NSLog(@"attempt %@", obj2); 

    [obj release]; // release because 'obj' is strong 
    [obj2 release]; // release because 'obj2' is strong. 
} 

이 튀어되어

, 일반적으로 발생합니다

이제
-(id) returnParam:(id) paramToReturn 
{ 
    // make sure the variable is in the scope for the entirety of the function 
    id returnValue = nil; 
    @try 
    { 
     // when the parameter is passed in, ARC will automatically retain it. 
     [paramToReturn retain]; 
     returnValue = [paramToReturn retain]; // strong assignment (a = b) 
     return returnValue; 
    } 
    @finally 
    { 
     [paramToReturn release]; // release the value we retained when we passed in the parameter 
     [returnValue autorelease]; // autorelease the return value so it is still valid after the function exits. 
    } 
} 

는 이제 다른 루프를 비교해 보자 iPhone 응용 프로그램의 다음 NSRunLoop 눈금 또는 콘솔 응용 프로그램의 @autoreleasepool 끝 부분에 표시됩니다.

+1

악기에서 위의 코드를 사용해 보셨습니까? 메서드와 루프가 모두 ARC 된 경우 옵티 마이저가 켜져 있으면 코드가 "방금 작업 한"경우 놀라지 않을 것입니다. 나는 또한 자동 응답 풀에 메모리를 accreted 경우 놀라지 않을 것입니다 ... – bbum

+0

@bbum 그게 내 대답은 뭐라고하지? '그러므로, 다음 autorelasepool이 터지기 전까지는 변수가 정리되지 않습니다 ... ' –

+0

@Richard 그건 의미가 있습니다. 나는 ARC가'autorelease'를 호출하여 객체를 반환 할 것이라는 것을 (충분히 깊이 생각하지 않고) 이해하지 못했습니다.그래서 아마 '거대한'루프가있을 때 객체를 반환하는 함수 (매개 변수 객체 일 필요는 없습니다)를 호출해서는 안된다는 표시 일 것입니다. 아니면 그 해결 방법을 알고 있습니까? – barley

관련 문제