-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

Try to initialize "q" ivar with a +1 retain count non-autoreleased object, like this:

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

Also you have to put all the code that will run on background thread into @autoreleasepool or NSAutoreleasePool. I think your program runs out of memory somehow. Example:

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

Also there's a problem with synchronization of ivars in your class. You are synchronizing self, but you are using "running" outside of synchronization scope. Also, the logic of the loop is unclear, you are running the loop just once, why do you need it at all?

于 2013-06-27T08:47:19.777 に答える
1

AFAIK [NSArray array] は、自動解放されたオブジェクトを返します。そのための参照が見つかりませんが。ARC を使用しないので、init メソッドに保持する必要があると思います。

于 2013-06-27T08:58:59.307 に答える
0

NSMutableArray *q1; が原因ではないでしょうか。count=[q1 count]; として使用する必要があります。and not count=[q count]; q??? ではなく q1 として宣言されているためです。

于 2013-11-20T09:19:35.687 に答える