简体   繁体   中英

Working with dispatch queues in Objective-c

I am very new to IOS, and I'm getting data from a webservice. This data I store into core-data. At the moment, I am loading in all of my data in, in the first view controller (tableview). But this takes about 10 min to fill up the tableview and store all the data in the core database. So I was wondering what the best practice is. So I want to work with dispatch queues. But what is the best way of using it?

  • First method

    1. First store data from first view
    2. Fill up tableview with this data
    3. store rest of the data in db.

But what if you go to the next view and not all data is loaded in?

  • Second method

    1. store data from first view
    2. Fill up tableview with this data?
    3. When the user goes to the second view, store data for second view
    4. Load second view with this data.

You always store the data correctly, but the user still needs to wait before it can use the app. (because the data is not loaded in for that view.)

At the moment I'm using the first method. And working with dispatch queues. I'm using it like this.

- (void)fetch1:(UIManagedDocument *)document
{
    dispatch_queue_t fetchQ = dispatch_queue_create("NewsFetch", NULL);
    dispatch_async(dispatch_get_main_queue(), ^{
        //store data in core database for firstViewController and save document.
        [document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
        [self loadFirstTableView];
        [self fetch2];
    });
    dispatch_release(fetchQ);

}
- (void)fetch2:(UIManagedDocument *)document
{
    dispatch_queue_t fetchAlbum = dispatch_queue_create("Album fetcher", NULL);
    dispatch_async(fetchAlbum, ^{
       //store data for secondViewController
        [document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];


    dispatch_release(fetchAlbum);
}

Can anybody help me?

Kind regards

EDIT

How I get my data from the webservice is at the following way.

 NSArray *news = [GenkData getNews]; //gets all the data from webservice as JSON
        for (NSDictionary *genkInfo in news) {
            [News newsWithGenkInfo:genkInfo  inManagedObjectContext:document.managedObjectContext];
        }
        [document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];

And this is how I setup my tableview.

- (void)setupFetchedResultsController // attaches an NSFetchRequest to this UITableViewController
{
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"News"];

    request.sortDescriptors = [NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES],nil];

    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                managedObjectContext:self.genkDatabase.managedObjectContext
                                sectionNameKeyPath:nil
                                cacheName:nil];

}

When you encounter performance issues, your first reaction should not be to introduce multi-threading. That adds extra complexity that should not be taken lightly and requires very careful attention to architecture.

Instead, I would highly recommend that you take a look at Ray Wenderlich's excellent tutorial about wiring up NSFetchedResultsController to a UITableView .

NSFetchedResultsController allows you to load in only the data you need and will automatically fetch batches of content as the user requests it. It will save you memory; it will take MUCH less time; it will make your users happy.

Check out the tutorial here: http://www.raywenderlich.com/999/core-data-tutorial-how-to-use-nsfetchedresultscontroller

Edit

So based on your edits, here's how I'd design your requirements.

  1. You should fetch the data from your web service using an asynchronous HTTP request. This is trivial to do using NSURLRequest and libraries like AFNetworking make this even easier.

  2. Since you're fetching the data from a web service, do you really need to then insert that data into Core Data? What would be simpler is to simply cache the HTTP response and then load your table view from that directly.

  3. Now that you have your HTTP response, tell the UITableView to reload. When it reloads, you provide the table data to it using the delegate methods. If you do not use Core Data, you won't need to mess with the NSFetchedResultsController any longer.

If your web service is returning massive amounts of data, you should probably code some paging mechanism to fetch results in batches. It would work like this: when the user reaches the end of the table view, you'd send another request to get the next 25 items. The general rule of thumb: don't fetch data until it's needed.

Finally, with all of this fetching, you're going to want to tell your user what's going on. Check out SVProgressHUD for that.

Hope that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM