[英]iOS - Objective-C - How to stop NSThread, when it's waiting?
我在這一個中有一個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;
}
}
謝謝!
我寫了一個簡單的demo,希望這可以幫到你:)
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
- (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停止等待
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.