How to cancel or stop NSThread?
Asked Answered
N

4

6

I'm doing an app that loads the contents of viewControllers using NSThread while is reading an XML file.

I have it done as follows:

-(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];
}

My problem is that I don't know how to stop the NSThread if the user changes to another viewController while the NSThread is loading, doing that the app crashes.

I've tried to cancel or exit the NSThread as follows but without success:

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

Can anyone help? Thanks.

Neal answered 13/9, 2011 at 11:42 Comment(1)
does your -(void)viewsDidDisappear:(BOOL)animated method called ?Spry
P
8

When you detach new thread, you can no more cancel or exit it from viewDidDisappear etc. These UI specific methods execute only on main thread so the exit/cancel applies to the main thread which is obviously wrong.

Instead of using the detach new thread method, declare NSThread variable in .h and initialize it using initWithTarget: selector: object: method and cancel it whenever/wherever you want to..

Peag answered 13/9, 2011 at 12:28 Comment(0)
S
1

you can also use [NSThread exit]; method of NSThread.

Spry answered 13/9, 2011 at 11:52 Comment(3)
I've tried this but this don't works for me, the app crashes =(Neal
using [NSThread exit] don't show a crash log, simply the app stops responding while the thread finishes. if I don't use Thread stop or cancel logs this: Terminate app due to uncaught exception 'NsInvalidArgumentException', reason: '-[__NSCFDictionary addSubview:]: unrecognized selector sent to instance...Neal
It seems like you exit from mainthread maybe. But check adding of subviews, may be you just use wrong object?Channel
A
0

It's better to let a thread end gracefully, i.e. reach its natural conclusion, if you can. It sounds like in your case you can afford to. Also be sure that you're updating the user interface from the main thread, not a secondary thread, as UIKit is not thread safe.

Aurelia answered 13/9, 2011 at 12:35 Comment(0)
A
0

You wrote: ... the app stops responding while the thread finishes...

Once you flag a thread for cancelling or exit, you have to manually stop whatever the thread was called to do. An example: ....

- (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;
    }

In this example, the loop is conditioned on the thread being in a non-cancelled state.

Atingle answered 10/6, 2016 at 4:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.