I’m getting a JSON feed with NSURLSessionDataTask and populating an NSMutableArray that is inside a shared store which is a singleton. The NSMutableArray is accessible to the outside world through a getter that casts it as an NSArray.
The getter calls a refresh method which polls the JSON feed and populates the NSMutableArray, like so:
- (NSArray *)articles
{
if ([_articles count] == 0) {
[self refreshArticles];
}
return _articles;
}
Here’s some of that method:
NSURLRequest *request = [NSURLRequest requestWithURL:feedURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:4.0];
NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
if (!error && response != nil) {
// decode JSON and add resultant objects to _articles
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Updated feed");
[nc postNotificationName:@"MLNArticleStoreFeedDidUpdate" object:self];
});
} else if (response == nil) {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"MLNNetworkError" object:self];
}
}];
[task resume];
This works, but every time the getter is called, the feed gets refreshed 7 times. I think this has to do with the getter's if clause continuing to be true while the feed downloads. I have mitigated this with dispatch_once, and it works but I feel like that's not right.
Here’s what the code is now:
- (NSMutableArray *)articles
{
if ([_articles count] == 0) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self refreshArticles];
});
}
return _articles;
}
But what I mean is: "if there are no articles, go get some, and then return". Is there a better way of doing this?