-1

下面是我的代码包含一个线程。这个线程负责队列大小,如果大小> 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

4 回答 4

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

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

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

于 2013-06-27T08:47:19.777 回答
1

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

于 2013-06-27T08:58:59.307 回答
0

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

于 2013-11-20T09:19:35.687 回答
0

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

运行良好...为什么?

于 2013-06-28T04:01:15.057 回答