我尝试将NSThread子类化,以便使用一些数据来操作线程。我想根据doc:
在python中模拟join()join():等到线程终止。这会阻塞调用线程直到 调用join()方法的线程终止
所以我认为使用performSelector:onThread:withObject:waitUntilDone:YES会好的,但它不起作用。它什么都不做,不会退出,就像永远一样。
这是我的代码:
@interface MyClass : NSThread
@property (strong, nonatomic) NSMutableArray *msgQueue;
@property (assign, nonatomic) BOOL stop;
@end
@implementation MyClass
-(id)init
{
self = [super init];
if (self) {
self.msgQueue = [NSMutableArray array];
self.stop = NO;
[self start];
return self;
}
return nil;
}
-(void)myRun
{
while (!self.stop) {
NSLock *arrayLock = [[NSLock alloc] init];
[arrayLock lock];
NSArray *message = [self.msgQueue firstObject];
[self.msgQueue removeObjectAtIndex:0];
[arrayLock unlock];
NSLog(@"%@", message);
if ([message[0] isEqualToString:@"terminate"]) {
self.stop = YES;
}
}
}
-(void)join
{
[self performSelector:@selector(myRun) onThread:self withObject:nil waitUntilDone:YES];
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
MyClass *a = [[MyClass alloc] init];
[a.msgQueue addObject:@[@"terminate",@"hello world"]];
//[a myRun]; // this line works so the myRun method should be good,
[a join]; // but I want this line work, and I have no idea what the problem is.
}
return 0;
}
答案 0 :(得分:1)
来自Apple关于performSelector:onThread:withObject:waitUntilDone:
的文档:
此方法使用默认的运行循环模式(即与NSRunLoopCommonModes常量关联的模式)在目标线程的运行循环上对消息进行排队。作为其正常运行循环处理的一部分,目标线程使消息出列(假设它在一个默认的运行循环模式下运行)并调用所需的方法。
您可能从未在线程上启动过运行循环,因此它永远不会执行您的myRun
方法,因为它没有执行的运行循环。
至于Merlevede的回答,myRun
没有排在与join
相同的主题上。在您的主线程上调用了join
,而您正在尝试将myRun
排入您的辅助线程。所以他的理论不正确。还有Apple关于等待参数的文档:
如果当前线程和目标线程相同,并且您为此参数指定了YES,则会立即在当前线程上执行选择器。如果指定NO,则此方法将消息排入线程的运行循环并返回,就像对其他线程一样。然后当前线程必须出列并在有机会时处理该消息。
所以,即使它在同一个线程上,它也不会等待,它会立即执行它,就像你直接调用方法而不是首先使用performSelector:
一样。 / p>
答案 1 :(得分:0)
你基本上处于僵局状态。
-(void)join
{
[self performSelector:@selector(myRun) onThread:self withObject:nil waitUntilDone:YES];
}
join
正在等待myRun
完成(waitUntilDone标志),但是myRun
在与join
相同的线程上排队,所以它也在等待{{1}完成。
对于join
,您永远不会将当前线程作为线程参数传递。