2011-01-24 4 views
3

그래서, [NSThread detachNewThreadSelector]를 사용하여 새 스레드를 생성하고 콘솔에 "autoreleased no pool in place"오류가 발생합니다. 자동 출시 풀을 만드는 데 실패하면이 문제가 발생할 수 있습니다.하지만 문제는 생성하는 것입니다. 동일한 앱의 다른 부분에서 유사한 코드를 사용하고 이러한 오류가 발생하지 않습니다.iOS가 풀없이 자동으로 풀립니다.하지만 ARP가 생성됩니다!

가 여기에 관련 코드입니다 :

- (void) startThread:(NSString*)strURL 
{ 
    // start new thread to load image 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    [NSThread detachNewThreadSelector:@selector(loadImageFromURL:) toTarget:self withObject:strURL]; 
    [pool release]; 
} 

- (void) loadImageFromURL:(NSString*)strURL 
{ 
    NSNumber* nn = [NSNumber numberWithInt:self.tag]; 
    NSLog(@"loadURL: Tag number == %i", [nn intValue]); 

    // other code here actually does the work 
} 

지금, 실제로 (원격 서버에서 이미지를로드하는) 작업을 수행 loadImageFromURL에 더 많은 코드가 있었다 -하지만 문제는 그 코드없이 자체 명단, 그래서 그것을 제거했습니다. (단지 당신이 아무것도하지 않는 무의미한 실을 가지고 있다고 생각하지 않습니다!). 문제를 나타내는 코드 한 줄만 남겨 두었습니다. 자동 반복 처리 된 NSNumber 객체가 만들어졌습니다. 이 코드를 실행하면

, 그것은 콘솔에이를보고

물론

__NSAutoreleaseNoPool(): Object 0x535c0e0 of class NSCFNumber autoreleased with no pool in place - just leaking

, 실제 코드가 다른 많은 AR 객체를 생성하고 그들 모두도보고받을.

도움이되는 팁이나 조언에 감사드립니다!

감사합니다.

답변

5

새 스레드를 만들 때 스레드에 대한 새 자동 풀을 만들어야합니다. 귀하의 경우에는, 그 추가로 간단 같습니다

loadImageFromURL:의 시작 부분에
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

과 끝에

[pool drain]; 

합니다.

만들려는 풀을 startThread:에 만들지 않아도됩니다. Threading Programming Guide, 특히 "스레드 입력 루틴 작성"섹션을 확인하십시오.

+0

칼 - 나는 당신의 시간을 낭비 죄송합니다. 당신은 물론 맞습니다. 그것은 * 내가 detachNewThreadSelector를 사용하는 앱의 다른 부분에서 어떻게 수행하고 있는지 *입니다. 나무 숲을 볼 수 없었습니다. 나는 틀린 패턴으로 고정되어 있었고 다른 코드를 보지 않았다. 나는 그것이 동일하다는 것을 확신했다. 빠른 응답 주셔서 감사합니다! – Jordan

4

코드에서 - (void) startThread:(NSString*)strURL은 주 스레드에서 실행 중이고 - (void) loadImageFromURL:(NSString*)strURL은 분리하려는 백그라운드 스레드에서 실행 중입니다.

메인 스레드에는 이미 NSAutoreleasePool이 있으므로 startThread:에 생성하는 스레드는 아마도 불필요합니다. 그러나 백그라운드 스레드는 NSAutoreleasePool을 만들지 않으므로 직접 작성해야합니다. @Carl Norum 제안 당신이 autorelelase 풀을 사용하여 수행하는 경우

또한
- (void) startThread:(NSString*)strURL 
{ 
    // start new thread to load image 
    [NSThread detachNewThreadSelector:@selector(loadImageFromURL:) toTarget:self withObject:strURL]; 
} 

- (void) loadImageFromURL:(NSString*)strURL 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    NSNumber* nn = [NSNumber numberWithInt:self.tag]; 
    NSLog(@"loadURL: Tag number == %i", [nn intValue]); 

    // other code here actually does the work 

    [pool drain]; 
} 

, 당신은 release 대신 drain를 사용해야처럼 코드에서

, 즉 보일 것이다.

+0

WRT는 드레인 대 방출을 사용합니다 - 모든 독서에서 (iOS에서) 그들은 동등하다는 것을 보여주었습니다. 그들 사이에 유일한 차이점은 iOS에없는 GC 하위 시스템에 대한 배수가 있다는 것입니다. 다른 이유가 있습니까? – Jordan

+0

나는 거기 있다고 생각하지 않는다. – pgb

+1

iOS 5 또는 6이 가비지 수집을 잘 처리 할 수 ​​있음을 잊지 마십시오. 그것은 또한 무료 토스트를 가질 수 있습니다. –

1

비슷한 문제가 있지만 ARC를 사용하는 경우의 해결책.

ARC를 사용하는 경우 "'NSAutoreleasePool'을 사용할 수 없음 : 자동 참조 계산 모드에서 사용할 수 없음"오류가 발생할 수 있습니다.

사용 :

- (void) startThread:(NSString*)strURL 
{ 
    // start new thread to load image 
    [NSThread detachNewThreadSelector:@selector(loadImageFromURL:) toTarget:self withObject:strURL]; 
} 

- (void) loadImageFromURL:(NSString*)strURL 
{ 
    @autoreleasepool {   
     NSNumber* nn = [NSNumber numberWithInt:self.tag]; 
     NSLog(@"loadURL: Tag number == %i", [nn intValue]); 

     // other code here actually does the work 
    } 
}