下面是我的代码,包括一个线程。该线程负责队列大小,如果大小>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;
}
AFAIK[NArray array]返回一个自动释放的对象。尽管我找不到这方面的参考资料。我认为您应该将其保留在init方法中,因为您没有ARC.
尝试用+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;
}
}
}
此外,在你的班级中,ivar的同步也存在问题。您正在同步self
,但使用的是同步范围之外的"正在运行"。此外,循环的逻辑也不清楚,你只运行了一次循环,为什么你需要它?
我如下重写线程代码。线程在"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);
}
}
}
运行良好。。。为什么?
不是因为NSMutableArray*q1;应使用count=[q1 count];而非计数=[q计数];因为它被声明为q1而不是q???