Как отменить или остановить NSThread? - PullRequest
6 голосов
/ 13 сентября 2011

Я делаю приложение, которое загружает содержимое viewControllers с помощью NSThread, пока читает файл XML.

Я сделал это следующим образом:

-(void)viewDidAppear:(BOOL)animated
{
    // Some code...


    [NSThread detachNewThreadSelector:@selector(loadXML) toTarget:self withObject:nil];
    [super viewDidAppear:YES];
}

-(void)loadXML{

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // Read XML, create objects...

    [pool release];
}

Моя проблема в том, что я не знаю, как остановить NSThread, если пользователь переключается на другой viewController во время загрузки NSThread, и это приводит к сбою приложения.

Я пытался отменить или выйти из NSThread следующим образом, но безуспешно:

-(void)viewsDidDisappear:(BOOL)animated{
    [NSThread cancel];
    // or [NSThread exit];
    [super viewDidDisappear:YES];
}

Кто-нибудь может помочь? Спасибо.

Ответы [ 4 ]

8 голосов
/ 13 сентября 2011

Когда вы отсоединяете новый поток, вы больше не можете отменить или выйти из него из viewDidDisappear и т. Д. Эти специфичные для пользовательского интерфейса методы выполняются только в основном потоке, поэтому выход / отмена применяются к основному потоку, что, очевидно, неверно.

Вместо использования метода отсоединения нового потока, объявите переменную NSThread в .h и инициализируйте ее, используя метод initWithTarget: selector: object:, и отмените ее всякий раз, когда / где вы хотите ..

1 голос
/ 13 сентября 2011

Вы также можете использовать [NSThread exit]; метод NSThread.

0 голосов
/ 10 июня 2016

Вы написали: ... приложение перестает отвечать, когда поток завершается ...

Как только вы помечаете поток для отмены или выхода, вы должны вручную остановить все, что поток был вызван, чтобы сделать. Пример: ....

- (void) doCalculation{
/* Do your calculation here */
}
- (void) calculationThreadEntry{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSUInteger counter = 0;
while ([[NSThread currentThread] isCancelled] == NO){

[self doCalculation];
    counter++;
    if (counter >= 1000){ break;
    } }
    [pool release]; }
    application:(UIApplication *)application
    - (BOOL)
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    /* Start the thread */
    [NSThread detachNewThreadSelector:@selector(calculationThreadEntry)
    toTarget:self withObject:nil];
    // Override point for customization after application launch. [self.window makeKeyAndVisible];
    return YES;
    }

В этом примере цикл обусловлен тем, что поток находится в неотменяемом состоянии.

0 голосов
/ 13 сентября 2011

Лучше, чтобы нить закончилась изящно, т. Е. Достигните своего естественного завершения, если можете. Похоже, в вашем случае вы можете себе это позволить. Также убедитесь, что вы обновляете пользовательский интерфейс из основного потока, а не из дополнительного потока, так как UIKit не является потокобезопасным.

...