1

I'm using chcsvparser to parse data from a csv file on my apps launch. It's taking way too long to startup on main thread so I was thinking of doing this on the background thread. But I read that you can't pass objects between the threads. The parser outputs an NSArray so is there a way to do this? I've also read that you shouldn't change UI from background thread but this array will load a table view.

Jon
  • 4,732
  • 6
  • 44
  • 67
  • I gather you can do anything in the background as long as you don't mix UI stuff with everything else in the background threads. – BoltClock Aug 06 '11 at 06:54

4 Answers4

8

You can always pass objects between threads.

Use the following code to create a thread and pass the object to it.

[NSThread detachNewThreadSelector:@selector(myThreadSelector:) toTarget:self withObject:myObject];

After the thread function is over you can pass the data back to the main thread using

[self performSelectorOnMainThread:@selector(myMainSelector:) withObject:myReturnObject waitUntilDone:NO];

you can pass the output NSArray from the parser to myMainSelector: and reload the tableview in it.

-(void)myMainSelector:(id)sender
{
    NSArray *arr = sender;
    tableDataArray = [NSArray arrayWithArray:arr];
    [yourTableView reloadData];
}

You can show an activity indicator while you are in the thread method.

ArunGJ
  • 2,685
  • 21
  • 27
2

The NSObject class has several different instance methods that allow you to invoke methods on the main UI thread. The performSelectorOnMainThread:withObject:waitUntilDone: method, for instance, allows you to invoke a method of the receiver on the main thread with the object of your choice.

Here's some code to get you started:

-(void) dataDoneLoading:(id) obj {
    NSMutableArray *array = (NSMutableArray *) obj;
    // update your UI
    NSLog(@"done");
}

-(void) myThread:(id) obj {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSMutableArray *array = [[[NSMutableArray alloc]init ]autorelease];

    // build up your array

    [self performSelectorOnMainThread:@selector(dataDoneLoading:) withObject:array waitUntilDone:NO];

    [pool release];    
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [NSThread detachNewThreadSelector:@selector(myThread:) toTarget:self withObject:nil];    
}
csano
  • 13,266
  • 2
  • 28
  • 45
  • Thanks j0k, I'm going to try this soon then imwill accept your answer. – Jon Aug 06 '11 at 07:21
  • Here is the actual code I will use to get the array. Do you think this will all work? I can't paste it cause I'm using my iPad right now. Thanks. http://stackoverflow.com/questions/6961367/basics-introduction-to-using-chcsvparser/6963881#6963881 – Jon Aug 06 '11 at 07:54
  • @Jon, I don't see why it wouldn't work. If you use the code Dave gave you to build your array and the code that I, along with others, have provided here, you should be OK. – csano Aug 06 '11 at 07:59
0

ofcourse we can pass objects to thread... please go through the link which shows how to process heavy task in background...

DShah
  • 9,768
  • 11
  • 71
  • 127
0

It is better to use NSOperation class to do that job. You can find a nice example named "LazyTableImages" at XCode documentation. It is uses a NSOperation to parse a XML

Joze
  • 668
  • 7
  • 13
  • Thanks Jose, ill look into that. In the meantime, can you check out the code I posted in the question and see if you can find a way to fix it so that the arrays all match up? – Jon Aug 06 '11 at 09:47
  • By using NSOperation you can reuse the data structure you defined with NSArray. Here [TumblrParseOperation](http://pastebin.com/j51PRHkx) you can see a little example of aJSON parser. I send the JSON as NSString and I receive the data as NSArray. – Joze Aug 06 '11 at 09:58
  • Sorry, there is a mistake on the pastebin example, on .h file, just type - (id)initWithData:(NSString *)jsonData delegate:(id )delegate; @end – Joze Aug 06 '11 at 10:02
  • The thread method and the NSOperation method are similar ways to do the same. To use NSOperation will be more easy to control it cuz you use a NSOperationQueue to perform the calls. You can see a nice tutorial here: [NSOperation And NSOperationQueue](http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/). Anyway, as you init the array as autorelease, maybe you need to send a copy of it. – Joze Aug 06 '11 at 10:36