NSThread崩溃[EXC_BAD_ACCESS]

时间:2013-06-27 08:35:00

标签: objective-c nsthread

下面是我的代码包含一个线程。这个线程注意队列大小,如果大小> 10然后记录并删除最后一个对象。但是当我运行demo = [[myDemo alloc] init]启动线程时,得到异常消息=“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通过@synchronized(self)

访问队列
-(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;
}

4 个答案:

答案 0 :(得分:1)

尝试使用+1保留计数非自动释放对象初始化“q”ivar,如下所示:

- (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;
}

此外,您必须将所有将在后台线程上运行的代码放入@autoreleasepoolNSAutoreleasePool。我认为你的程序以某种方式耗尽内存。例如:

- (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,但您正在同步范围之外使用“正在运行”。 此外,循环的逻辑不清楚,你只运行一次循环,为什么你需要它?

答案 1 :(得分:1)

AFAIK [NSArray数组]返回一个自动释放的对象。虽然我只是没有找到参考。我认为你应该在init方法中保留它,因为你没有ARC。

答案 2 :(得分:0)

我重写了如下的线程代码。在“while loop”运行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);       
            }
        }
    }

运行正常......为什么?

答案 3 :(得分:0)

不是因为  NSMutableArray * q1;应该用作count = [q1 count];而不算= [q count];因为它被声明为q1而不是q ???