vodkhang
vodkhang

Reputation: 18741

Asynchronous callback for network in Objective-C Iphone

I am working with network request - response in Objective-C. There is something with asynchronous model that I don't understand.

In summary, I have a view that will show my statuses from 2 social networks: Twitter and Facebook. When I clicked refresh, it will call a model manager. That model manager will call 2 service helpers to request for latest items. When 2 service helpers receive data, it will pass back to model manager and this model will add all data into a sorted array.

What I don't understand here is that : when response from social networks come back, how many threads will handle the response. From my understanding about multithreading and networking (in Java), there must have 2 threads handle 2 responses and those 2 threads will execute the code to add the responses to the array. So, it can have race condition and the program can go wrong right? Is it the correct working model of iphone objective-C? Or they do it in a different way that it will never have race condition and we don't have to care about locking, synchronize?

Here is my example code:

ModelManager.m

- (void)updateMyItems:(NSArray *)items {
    self.helpers = [self authenticatedHelpersForAction:NCHelperActionGetMyItems];
    for (id<NCHelper> helper in self.helpers) {
        [helper updateMyItems:items]; // NETWORK request here
    }
}

- (void)helper:(id <NCHelper>)helper didReturnItems:(NSArray *)items {
     [self helperDidFinishGettingMyItems:items callback:@selector(model:didGetMyItems:)];
         break;                     
    }
}

// some private attributes
int *_currentSocialNetworkItemsCount = 0; // to count the number of items of a social network
- (void)helperDidFinishGettingMyItems:(NSArray *)items {
        for (Item *item in items) {
            _currentSocialNetworkItemsCount ++;
        }            
        NSLog(@"count: %d", _currentSocialNetworkItemsCount);
        _currentSocialNetworkItemsCount = 0;
}

I want to ask if there is a case that the method helperDidFinishGettingMyItems is called concurrently. That means, for example, faceboook returns 10 items, twitter returns 10 items, will the output of count will ever be larger than 10?

And if there is only one single thread, how can the thread finishes parsing 1 response and jump to the other response because, IMO, thread is only executed sequently, block of code by block of code

Upvotes: 0

Views: 2083

Answers (1)

Tom Dalling
Tom Dalling

Reputation: 24125

Yes, there is probably a thread per network request. The trick is to handle the response on the main thread. You should have something like this:

- (void)helper:(id <NCHelper>)helper didReturnItems:(NSArray *)items;
{
    [self performSelectorOnMainThread:@selector(helperDidFinishGettingMyItems:)
                           withObject:items
                        waitUntilDone:NO];
}

Putting the response back onto the main thread will avoid a whole bunch of multithreading problems.

Also, the output of count will never be larger than 10. It's just that multiple threads may be running helperDidFinishGettingMyItems: at the same time. They won't automatically combine the two arrays.

The counter could possibly be more than 10, because multiple threads could be increasing that ivar at the same time.

Upvotes: 1

Related Questions