2013-06-27 3 views
-1

아래 코드는 스레드를 포함합니다.이 스레드는 크기가 10보다 크면 로그를 남기고 마지막 객체를 제거합니다. 그러나 데모 = [[myDemo alloc] init]을 실행하면 다음과 같이됩니다. 스레드를 시작하고 예외 메시지 = "EXC_BAD_ACCESS"를 얻습니다. 어떤 사람이이 문제를 해결하도록 도와 주시겠습니까?NSThread 크래시 [EXC_BAD_ACCESS]

@interface myDemo:NSObject 
    { 
     NSMutableArray *q; 
     NSThread  *thread; 
     bool   running; 
    } 

    -(void)putData:(NSData *)data; 
    -(NSData *)popData; 
    -(void)stopThread; 
    @end; 

@implementation myDemo 
    -(id)init 
    { 
     if(NULL!=(self = [super init])) 
     { 
      q=[NSMutableArray array]; 
      thread=[[NSThread alloc] initWithTarget:self 
              selector:@selector(myThreadMainMethod:) 
              object:nil]; 
      [thread start]; 
     } 
     return self; 
    } 
    -(void)myThreadMainMethod:(id)object 
    { 
     unsigned long count; 
     NSData *data; 
     if(running) return; 
     running=true; 
     while(running) 
     { 
      @synchronized(self) 
      { 
       count=[q count];//crash !!!! 
       if(count>10) 
       { 
        data=[q lastObject]; 
        NSLog(@"count=%d ,remove last data=%@",count,[[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); 
        [q removeLastObject]; 

       } 
      } 
     } 
     running=false; 
    } 

putData 및 popData가 +1와 "Q"바르 이렇게 비 오토 릴리즈 객체 카운트 유지 초기화하는

-(void)putData:(NSData *)data 
{ 
    @synchronized(self) 
    { 
     [q addObject:data]; 
    } 
} 
-(NSData *)popData 
{ 
    NSData * data=NULL; 
    unsigned long count; 
    @synchronized(self) 
    { 
     count=[q count]; 
     if(count!=0) 
     { 
      data=[q lastObject]; 
      [q removeLastObject]; 
     } 
    } 
    return data; 
} 
+0

'q'는 어떻게 선언합니까? –

+0

ARC를 사용하고 있습니까? –

+0

@ Daij-Djan 그는 "[[NSString alloc] initWithData : data encoding : NSUTF8StringEncoding] autorelease] 행을 봅니다." –

답변

1

시도 @synchronized (자체)에 의해 큐에 액세스 할 수 있습니다

- (id)init 
{ 
    if (self = [super init]) 
    { 
     q = [[NSMutableArray alloc] initWithCapacity:10]; 
     thread = [[NSThread alloc] initWithTarget:self 
             selector:@selector(myThreadMainMethod:) 
              object:nil]; 
     [thread start]; 
    } 
    return self; 
} 

또한 백그라운드 스레드에서 실행되는 모든 코드를 @autoreleasepool 또는 NSAutoreleasePool으로 입력해야합니다. 나는 당신의 프로그램이 어쨌든 메모리 부족하다고 생각한다. 예 :

- (void)myThreadMainMethod:(id)object 
{ 
    @autoreleasepool { 
     static unsigned long count; 
     NSData *data = nil; 
     if (running) { 
      return; 
     } 
     running = true; 
     while (running) 
     { 
      @synchronized(self) 
      { 
       count=[q count];//crash !!!! 
       if(count>10) 
       { 
        data=[q lastObject]; 
        NSLog(@"count=%d ,remove last data=%@",count, 
          [[[NSString alloc] initWithData:data 
               encoding:NSUTF8StringEncoding] 
          autorelease]); 
        [q removeLastObject]; 
       } 
      } 
      running=false; 
     } 
    } 
} 

또한 클래스의 ivars 동기화에 문제가 있습니다. self을 (를) 동기화하고 있지만 동기화 범위 외부에서 "실행 중"을 사용 중입니다. 또한 루프의 논리가 불분명합니다. 루프를 한 번 실행하고 있는데 왜 필요합니까?

+0

당신의 제안과 함께 테스트하지만 여전히 충돌 – luckfox0927

+0

@ luckfox0927 내 대답을 편집했습니다 체크 아웃 –

+0

UR 도움말 주셔서 감사!이 플래그는 "실행"이상 "동안"해야합니다. – luckfox0927

1

AFAIK [NSArray array]는 자동 렌더링 된 객체를 반환합니다. 비록 내가 그것에 대한 참조를 찾지는 못했지만. 나는 당신이 ARC를하지 않는 것처럼 그것을 초기화 메소드에서 유지해야한다고 생각한다.

0

나는 below.thread 후 충돌이 있었다으로 "루프 동안"564 번 다음

-(void)myThreadMainMethod:(id)object 
    { 
     unsigned long count,index=0; 
     NSData *data; 
     NSMutableArray *q1; 
     if(running) return; 
     running=true; 

     q1=[NSMutableArray array]; 
     while(running) 
     { 
      @synchronized(self) 
      { 

       count=[q count];//crash !!! 
       NSLog(@"#%d count=%d ",index++,count); 

      } 
     } 
    } 

내가 잘 ... 왜

-(void)myThreadMainMethod:(id)object 
    { 
     unsigned long count,index=0; 
     NSData *data; 
     NSMutableArray *q1; 
     if(running) return; 
     running=true; 

     q1=[NSMutableArray array]; 
     while(running) 
     { 
      @synchronized(self) 
      { 

       count=[q1 count];//run fine 
       NSLog(@"#%d count=%d ",index++,count);  
      } 
     } 
    } 

실행 아래로 다시 재 작성을 실행 스레드 코드를 다시 작성?

+0

실제 답변없이 직접 질문에 대한 답변을 추가하는 대신 원본 질문을 편집하십시오. 문제점 : 매우 잘못된 방식으로 스레드를 관리하고 있습니다. 이 가이드를 읽으십시오. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html –

0

이 아니기 때문에 NSMutableArray * q1; count = [q1 count];로 사용되어야합니다. 그리고 count = [q count]가 아닌; 왜냐하면 그것은 q1이 아니라 q라고 선언 되었기 때문입니다.