У меня довольно стандартная настройка. У меня есть UIViewController для обработки взаимодействия с пользователем и несколько долго работающий NSThread, который выполняет реальную работу, когда появляется UI Controller. У меня была одна проблема, когда я хочу отменить NSThread. Стандартная семантика NSThread в порядке. Я хочу, чтобы поток завершился, очистил себя (чтобы освободить ссылку на мой UIViewController), а затем вытолкнул UIViewController. Итак, мой код выглядит примерно так:
В селекторе NSThread:
-(void) nsThreadWork
{
// do work here
@synchronized(self)
{
[nsThreadInstance release];
nsThreadInstance = nil;
}
}
В UIViewController, который порождает поток:
-(void) startThread
{
nsThreadInstance = [[NSThread alloc] initWithTarget:self
selector:@(nsThreadWork) ...];
[nsThreadInstance start];
[nsThreadInstance release];
}
И если я хочу отменить:
// assume that this will be retried until we can execute this successfully.
-(void) cancelBackgroundOpAndPopViewController
{
@synchronized(self)
{
if (nsThreadInstance == nil)
{
[self popViewController];
}
}
}
Я сомневаюсь, что это правильно, хотя. Проблема в том, что элементами пользовательского интерфейса можно манипулировать только из основного потока. Если я вытолкну контроллер представления до выхода из NSThread, NSThread выйдет и освободит контроллер представления, что означает, что он будет освобожден из контекста NSThread, что вызовет утверждение. Кажется, все работает правильно с приведенным выше кодом, но я не понимаю, когда runloop освобождает NSThread. Кто-нибудь может дать какое-либо понимание?