我有一个nsthread,while循环。它从主方法中的“线程安全”队列中获取对象。当我离开包含这个nsthread对象的UIViewController时,我调用了nsthread取消方法,但它没有停止,因为它被“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;
}
}
谢谢!
答案 0 :(得分: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
答案 1 :(得分: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停止等待