iOS-Objective-C-如何停止NSThread,当它';她在等什么?
我有一个nsthread,其中有一个while循环。它从main方法中的“线程安全”队列中获取对象。当我离开包含此nsthread对象的UIViewController时,我调用nsthread cancel方法,但它没有停止,因为它被“queueLock”NSCondition锁定。返回此UIViewController时,将创建一个新的nsthread并从队列中获取对象,但前一个线程仍然存在,并且两个线程都试图使用队列中的同一对象,这会导致内存管理问题。我的问题是,当我离开UIViewController时,应该如何停止此线程 NSThread主方法:iOS-Objective-C-如何停止NSThread,当它';她在等什么?,ios,objective-c,locking,nsthread,nscondition,Ios,Objective C,Locking,Nsthread,Nscondition,我有一个nsthread,其中有一个while循环。它从main方法中的“线程安全”队列中获取对象。当我离开包含此nsthread对象的UIViewController时,我调用nsthread cancel方法,但它没有停止,因为它被“queueLock”NSCondition锁定。返回此UIViewController时,将创建一个新的nsthread并从队列中获取对象,但前一个线程仍然存在,并且两个线程都试图使用队列中的同一对象,这会导致内存管理问题。我的问题是,当我离开UIViewCon
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;
}
}
谢谢
- (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停止等待我编写了一个简单的演示,希望这能帮助您:) demo.h
#import <Foundation/Foundation.h>
@interface test : NSObject
{
NSCondition *queueCondition;
NSThread *queueThread;
NSMutableArray *queueTask;
NSTimer *timer;
}
- (id)init;
@end
谢谢我尝试了这一点,但第二次打开UIViewController时,我在[pool drain]行收到了一个“[Not A Type release]:message sent to deallocated”错误,并且第一个线程仍然存在。我在UIViewController的ViewDidDemouse方法中调用了线程取消方法。谢谢,我将尝试一下。谢谢您的编写!我使用您编写的这个很好的演示来理解NSThread以及如何对数据进行排队。虽然现在每个人都指向GCD,但我认为记住NSThread的“手工完成”选项很重要。
#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