1110
1110

Reputation: 6829

How to put for loop to a separate thread

I have for loop that can read up to 100k rows.
When I start this function it block my UI until its done.

for (Item* sp in items){
    data = [data stringByAppendingFormat:@"\"%@\",\"%@\","\n", ....];
}

How can I put this to separate thread so it doesn't block UI?

Upvotes: 0

Views: 84

Answers (4)

Mark
Mark

Reputation: 6128

If order doesn't matter in your loop I prefer to use dispatch_apply() inside of dispatch_async(). The difference is that a traditional for(...) loop will put all of the work on a single thread, while dispatch_apply() will perform the individual iterations in parallel on multiple threads, but as a whole the loop is synchronous, where the loop will not exit until all of the processing is complete.

A good test to see if order matters in your loop is whether the loop can be performed backwards with the same results.

Upvotes: 0

Tapas Pal
Tapas Pal

Reputation: 7207

Best way to use NSInvocationOperation.

NSOperationQueue *OperationQueue=[[NSOperationQueue alloc] init];
NSInvocationOperation *SubOperation=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(LoopOperation) object:nil];

[SubOperation setQueuePriority:NSOperationQueuePriorityVeryHigh]; //You can also set the priority of that thread.
[OperationQueue addOperation:SubOperation];


-(void)LoopOperation
{
    for (Item* sp in items)
    {
        data = [data stringByAppendingFormat:@"\"%@\",\"%@\","\n", ....];
    }

    dispatch_async(dispatch_get_main_queue(), ^{

        //UI updates using item data 

        });
}

Upvotes: 0

wesley
wesley

Reputation: 859

This may suits you

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

        for(Item* sp in items)
        {
            data = [data stringByAppendingFormat:@"\"%@\",\"%@\","\n", ....];
        }

            dispatch_async(dispatch_get_main_queue(), ^{

            //UI updates using item data 

            });


    });

Upvotes: 0

trojanfoe
trojanfoe

Reputation: 122391

I don't think you've provided a complete example, but the simple use of Grand Central Dispatch should do the trick:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    for (Item* sp in items){
        data = [data stringByAppendingFormat:@"\"%@\",\"%@\","\n", ....];
    }

    // Then if you want to "display" the data (i.e. send it to any UI-element):
    dispatch_async(dispatch_get_main_queue(), ^{
        self.someControl.data = data;
    });

    // else simply send the data to a web service:
    self.webService.data = data;
    [self.webService doYourThing];

});

Upvotes: 2

Related Questions