下面是我的代码包含一个线程。这个线程注意队列大小,如果大小> 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;
}
答案 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;
}
此外,您必须将所有将在后台线程上运行的代码放入@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
,但您正在同步范围之外使用“正在运行”。
此外,循环的逻辑不清楚,你只运行一次循环,为什么你需要它?
答案 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 ???