Я пытаюсь понять концепцию RunLoops. Я прочитал руководство разработчика Apple по RunLoops и в некоторой степени понял концепцию RunLoops. Чтобы сделать мою концепцию более понятной, я написал очень простой код, в котором используется RunLoops. Код можно увидеть ниже.NSRunLoop- Требуется уточнение
- (void)viewDidLoad
{
[super viewDidLoad];
thread = [[NSThread alloc] initWithTarget:self selector:@selector(testMethod) object:nil];
[thread start];
}
- (void)testMethod {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSLog(@"Thread Entered");
NSMachPort* dummyPort = [[NSMachPort alloc] init];
[[NSRunLoop currentRunLoop] addPort:dummyPort forMode:NSDefaultRunLoopMode];
while(!exitThread) {
NSLog(@"Thread did some work");
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
[[NSRunLoop currentRunLoop]
removePort:dummyPort
forMode:NSDefaultRunLoopMode];
[dummyPort release];
NSLog(@"Thread Exited");
[pool drain];
}
- (IBAction)doDomeWorkOnBackgroundThread:(id)sender {
[self performSelector:@selector(dummyMethod) onThread:thread withObject:nil waitUntilDone:NO];
}
- (IBAction)exitThread:(id)sender {
[self performSelector:@selector(exitBackgroundThread) onThread:thread withObject:nil waitUntilDone:NO];
}
- (void)exitBackgroundThread {
exitThread = YES;
}
- (void)dummyMethod {
//Empty
}
В коде выше я создаю фоновый поток и на этом фоне нить я звоню функцию testMethod
. Внутри testmethod
Я запускаю while, который проверяет переменную BOOL exitThread
и запускает RunLoop фонового потока с использованием метода NSRunLoop - (BOOL)runMode: beforeDate:
. Есть два IBActions, которые прикреплены к двум кнопкам. Поскольку имя IBActions предполагает, что один из них - exitThread
, а другой - пробудить поток и выполнить инструкцию NSLog, записанную во время цикла while.
Приведенный выше код работает так, как я ожидал. Всякий раз, когда выполняется метод doDomeWorkOnBackgroundThread
, поток просыпается из его runloop, выполняет следующую итерацию цикла while, проверяет переменную BOOL exitThread
и находит ее значение как false, проходит внутри цикла while и выполняет инструкцию NSlog. Аналогично При использовании метода exitThread:
переменная exitThread
имеет значение true, из-за чего цикл while и поток завершаются.
Однако мне нужно несколько уточнений:
1) Если вместо того, чтобы использовать runMode: beforeDate:
в цикле в то время как я использую run
или runUntilDate:
метод NSRunLoop, то поток никогда не выбрасываемые при exitThread:
метод выполняется. Метод exitBackgroundThread вызывается в фоновом потоке, но цикл while никогда не выполняет его следующую итерацию (как при использовании runMode: beforeDate:
), и поэтому поток никогда не выходит.
2) Я попытался изменить exitBackgroundThread
метод
- (void)exitBackgroundThread {
exitThread = YES;
CFRunLoopStop(CFRunLoopGetCurrent());
}
Поскольку exitBackgroundThread
выполняется на фоне резьбы CFRunLoopGetCurrent() должен дать RunLoop фонового потока. Поэтому это должно идеально остановить цикл запуска фонового потока независимо от того, какой метод NSRunLoop я использую для запуска RunLoop. Поэтому в любом случае поток должен выйти по вызову функции выше. Но этого просто не происходит.
Я знаю, что у меня что-то не хватает, и с моей стороны я делаю огромное количество googling, чтобы найти ответ на этот вопрос, но просто не могу найти правильный ответ.
** EDIT
Я нашел this вопрос, который очень похож на мой первый запрос. Это в значительной степени устраняет мои первые сомнения.
Привет, спасибо большое за такое подробное объяснение. Однако я мог найти CFRunLoopRun() только в документации. Но все-таки это сработало. – tek3