3

nsthreadがあり、この中にwhileループがあります。mainメソッドの「スレッドセーフ」キューからオブジェクトを取得しています。このnsthreadオブジェクトを含むUIViewControllerを離れるとき、nsthread cancelメソッドを呼び出しますが、「queueLock」NSConditionによってロックされているため、停止しません。このUIViewControllerに戻ると、新しいnsthreadが作成され、オブジェクトがキューから取得されますが、前のスレッドは引き続き終了し、両方がキューから同じオブジェクトを使用しようとするため、メモリ管理の問題が発生します。私の質問は、UIViewControllerを離れるときに、このスレッドをどのように停止する必要があるかです。

NSThreadのメインメソッド:

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
while ([self isCancelled] == NO) {
    RenderRequest *renderRequest = [queue get];
    [self doRender:renderRequest];
    [renderRequest release];    
}

[pool drain];

これは、キュークラスのgetメソッドです。

- (id) get {
    id toRet = nil;
    [queueLock lock];
    @try {
       while ([queueContents count] == 0) {
            [queueLock wait];
        }

        toRet = [queueContents lastObject];
        [queueContents removeLastObject];
    }

    @finally {
         [queueLock unlock];
         return toRet;
    }
}

ありがとう!

4

2 に答える 2

1

私は簡単なデモを書きました、これがあなたを助けることができることを願っています:)

demo.h

#import <Foundation/Foundation.h>

@interface test : NSObject
{
    NSCondition *queueCondition;
    NSThread *queueThread;

    NSMutableArray *queueTask;

    NSTimer *timer;
}
- (id)init;
@end

demo.m

#import "demo.h"

@interface demo (PrivateMethods)
- (void)threadTest;
- (void)cancelThread;
- (void)addTask;
@end


@implementation demo

- (id)init
{
    self = [super init];
    if (self) {
        if (!queueThread) {
            if (!queueCondition) {
                queueCondition = [[NSCondition alloc] init];
            }

            if (!queueTask) {
                queueTask = [[NSMutableArray alloc] initWithCapacity:5];
            }

            queueThread = [[NSThread alloc] initWithTarget:self selector:@selector(threadTest) object:nil];
            [queueThread start];

            [self performSelector:@selector(cancelThread) withObject:nil afterDelay:10];

            if (!timer) {
                timer = [[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(addTask) userInfo:nil repeats:YES] retain];
            }
        }
    }
    return self;
}

- (void)dealloc
{
    [queueThread release];
    [queueCondition release];
    [queueTask release];
    [timer invalidate];
    [timer release];
    [super dealloc];
}

- (void)threadTest
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    while (![[NSThread currentThread] isCancelled]) {
        [queueCondition lock];
        [queueCondition wait];

        if ([queueTask count] == 0) {
            [queueCondition unlock];
            continue;
        }

        NSString *str = nil;
        while ((str = [queueTask lastObject])) {
            NSLog(@"getTask: %@", [queueTask lastObject]);
            [queueTask removeLastObject];

        }

        [queueCondition unlock];
    }
    NSLog(@"threadTest end");
    [pool drain];
}

- (void)addTask
{
    [queueCondition lock];
    if (!queueTask) {
        queueTask = [[NSMutableArray alloc] initWithCapacity:5];
    }
    [queueTask addObject:@"new task"];
    [queueCondition signal];
    NSLog(@"add: new task");
    [queueCondition unlock];
}

- (void)cancelThread
{
    [timer invalidate];

    [queueThread cancel];

    [queueCondition lock];
    [queueCondition signal];
    [queueCondition unlock];
}
@end
于 2012-03-29T09:51:48.213 に答える
0
- (id) get
{
    id toRet = nil;
    [queueLock lock];
    @try
    {
        while ([queueContents count] == 0)
        {
            [queueLock wait];
            if ([self isCancelled]) return nil; // stop waiting
        }

        toRet = [queueContents lastObject];
        [queueContents removeLastObject];
    }
    @finally
    {
         [queueLock unlock];
         return toRet;
    }
}

スレッドメイン

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

while ([self isCancelled] == NO)
{
    RenderRequest *renderRequest = [queue get];
    if (renderRequest == nil) break; // should stop
    [self doRender:renderRequest];
    [renderRequest release];    
}

[pool drain];

次に、スレッドをキャンセルして、queueLockに通知して待機を停止することができます

于 2012-03-29T09:37:30.470 に答える