我正在使用NSURLSessionDataTask获得一个JSON提要,并在共享存储区(即单例存储)中填充一个NSMutableArray。外部世界可以通过一个将NSMutableArray转换为NSArray的getter来访问它。
getter调用一个刷新方法,该方法轮询JSON提要并填充NSMutableArray,如下所示:
- (NSArray *)articles
{
if ([_articles count] == 0) {
[self refreshArticles];
}
return _articles;
}下面是其中的一些方法:
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];这是可行的,但每次调用getter时,提要都会刷新7次。我认为这与getter的if子句有关,而feed下载则继续为真。我已经用dispatch_once减轻了这种情况,但是我觉得这是不对的。
下面是代码的内容:
- (NSMutableArray *)articles
{
if ([_articles count] == 0) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self refreshArticles];
});
}
return _articles;
}但我的意思是:“如果没有文章,去拿一些,然后然后回来”。有更好的方法吗?
发布于 2015-04-30 16:48:02
以这种方式使用的dispatch_once不会做您想要做的事情。这里真正的问题是,您几乎可以肯定,不希望在返回之前等待网络活动。如果你像这样阻止主线程,操作系统会杀死你的应用程序。
- (NSArray *)articles
{
if ([_articles count] == 0) {
[self refreshArticlesFromNetwork];
}
return _articles;
}
- (void)refreshArticlesFromNetwork
{
if (self.networkRefreshInProgress)
return;
self.networkRefreshInProgress = YES;
[self showNetworkLoadingUI];
NSURLRequest *request = [NSURLRequest requestWithURL:feedURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:4.0];
NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
NSMutableArray* localArray = [NSMutableArray array];
if (!error && response != nil) {
// decode JSON and add resultant objects to local array
[localArray addObject: ... ];
}
dispatch_async(dispatch_get_main_queue(), ^{
_articles = [localArray copy];
self.networkRefreshInProgress = NO;
[self hideNetworkLoadingUI];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
if (!error && response != nil) {
[nc postNotificationName:@"MLNArticleStoreFeedDidUpdate" object:self];
} else if (response == nil) {
[nc postNotificationName:@"MLNNetworkError" object:self];
}
NSLog(@"Updated feed");
});
}];
[task resume];
}这里的重点是:
https://stackoverflow.com/questions/29972508
复制相似问题