2009-02-03 3 views
2

개체가 있고 해당 개체에서 일부 스레드로드를 수행하기 위해 스레드를 시작합니다.두 번째 호출에서 NSThread 충돌 (iPhone)

데이터를 반환 할 때 주 스레드에서 수행 할 선택자를 호출합니다.

첫 번째 호출에서는 올바르게 작동하지만 두 번째로는 오류가 발생하지 않습니다 (특정 오류 없음). 내가 performSelectorOnMaintThread를 호출 할 때

[NSThread detachNewThreadSelector:@selector(doThread:) 
         toTarget:self 
         withObject:@"lala"]; 

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


DataModelLocator *mydelegate = [DataModelLocator instance]; 
NSData *postData = [poststring dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO]; 
NSURL *url = [NSURL URLWithString:[mydelegate fwaservicepath]]; 

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 

[request setURL:url]; 
[request setHTTPMethod:@"POST"]; 
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"]; 
[request setHTTPBody:postData]; 

NSURLResponse *urlResponse; 

NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:nil]; 

if(data) { 
    [self performSelectorOnMainThread:@selector(loadDidFinishWithData:) 
          withObject:data 
         waitUntilDone:YES]; 
    //[self loadDidFinishWithData:data]; 
} else { 
    [self performSelectorOnMainThread:@selector(loadDidFinishWithError:) 
          withObject:data 
         waitUntilDone:YES]; 
} 
[pool release]; 

} 
} 

그것은이 출시 왔을 때,이 싱글에 충돌하는 것이 될 수 ... 충돌?

답변

4

스레드를 처리 할 때 전염병과 같은 자동 렌더링 된 객체는 사용하지 마십시오. 자동 복구 풀이 비 결정적 시간에 소모되어 재미난 충돌이 발생합니다. 관련된 모든 객체에 대해 alloc/init 및 release를 사용하고 performSelectorOnMainThread 또는 detachNewThreadSelector를 사용하여 다른 스레드에서 호출되는 메서드에서 가져 오는 모든 객체를 유지해야합니다.

Mac에서의 가비지 수집은 이러한 문제를 효과적으로 해결하지만, iPhone은 곧 그럴 것입니다.

+1

또한 프레임 워크의 많은 메소드가 자동 반복 객체를 작성하기 때문에 누출을 피하기 위해 스레드 당 최소 하나의 자동 해제 풀을 작성해야합니다 (수명이 긴 스레드가 자주 유출되는 경우) – rpetrich

0

문제에 대한 추가 정보 (두 줄의 충돌, 지금까지 디버깅 한 내용 등)를 게시하여 더 좋은 제안을 제공 할 수 있습니다. 어느 라인이 문제를 일으키는 지 알지 못한다면 나는 추측 할 위험이있다. 소리가 나면 자동 가비지 콜렉션에 의해 정리되는 객체가있을 것이다.

변수 "데이터"는 어디서 오는가? 당신이 개인 멤버 변수와 헤더 파일을 만드는 경우 같은있을 수 있습니다 : 다음과 같이 초기화 된 변수는 일반적으로 오토 릴리즈됩니다

NSSomeType *data = [NSSomeType builtInInitFunction]; 

,하지만 당신은 아마 있는지 확인하려면 그 쓰레기 수거 객체의 인스턴스를 보유합니다. 다음과 같이 시도하십시오 :

// Objects initialized with init are retained 
NSSomeType *data = [[NSSomeType alloc] init]; 

// Objects that would normally be autoreleased can be marked as retain 
NSSomeType *data = [[NSSomeType builtInInitFunction] retain]; 

코드가 어떻게 구성되어 있는지 모르겠지만 모든 유지 및 초기화에 적어도 하나의 릴리스를 추가하십시오! 나는 여전히 Objective-C에 상당히 익숙하다. 그래서 장님을 인도하는 사람과 조금 같아서 소금 한 알로 충고한다.

자세한 내용은 Learn Objective-C의 "메모리 관리에 대한 추가 정보"섹션을 확인하십시오.

EDIT2 : 명확한 예제 코드. 도움을 주신 Evan (의견)에게 감사드립니다.

EDIT3 : Brad와 (과) 일치합니다. alloc/init/release를 직접 처리하는 AutoRelease 풀을 제거하는 것이 좋습니다. NSURLConnection 객체에 대해 충분히 알지 못하지만 Autorelease로 표시된 데이터 메모리가 있습니까? 그렇다면 다른 방법으로 초기화하거나 보유를 사용해야 할 수도 있습니다.

디버거에서 코드를 단계별로 실행하십시오. A) 정확히 어떤 라인이 충돌하고 있는지 그리고 B) 모든 변수의 값을 찾아 낸다. 운이 좋으면 하나가 아님을 알 수 있습니다.

+0

alloc은 retain 역할을하므로 여분의 retain 호출을 추가하면 누수가 발생합니다 (해당 [data release]는 보유 횟수를 한 번 감소 시키지만 alloc 및 명시 적 보유로 증가됩니다). –

+0

하지만 나는 당신이 옳은 길에 있다고 생각합니다. 첫 번째 호출 이후 두 번째 전에 데이터가 가비지 수집되거나 해제 될 수 있습니다. –

관련 문제