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.

karse23
  • 4,055
  • 6
  • 29
  • 33

4 Answers4

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..

Swapnil Luktuke
  • 10,385
  • 2
  • 35
  • 58
1

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

Maulik
  • 19,348
  • 14
  • 82
  • 137
  • I've tried this but this don't works for me, the app crashes =( – karse23 Sep 13 '11 at 11:54
  • 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... – karse23 Sep 13 '11 at 12:02
  • It seems like you exit from mainthread maybe. But check adding of subviews, may be you just use wrong object? – Valerii Pavlov Nov 28 '12 at 20:32
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.

James Bush
  • 1,485
  • 14
  • 19
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.

Ken
  • 30,811
  • 34
  • 116
  • 155