2015-07-21 35 views
0

最近我开始为iOS开发,面临的问题可能很明显,但我自己无法弄清楚。 我想要做的是使用GCD提供的多线程来执行另一个任务。接下来执行任务

这是我取的JSON代码(放在类单) CategoriesStore

- (instancetype)initPrivate { 
    self = [super init]; 

    if (self) { 
     [self sessionConf]; 

     NSURLSessionDataTask *getCategories = 
     [self.session dataTaskWithURL:categoriesURL 
        completionHandler:^(NSData *data, 
             NSURLResponse *response, 
             NSError *error) { 
         if (error) { 
          NSLog(@"error - %@",error.localizedDescription); 
         } 

         NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *) response; 

         if (httpResp.statusCode == 200) { 
          NSError *jsonError; 

          NSArray *json = 
          [NSJSONSerialization JSONObjectWithData:data 
                  options:NSJSONReadingMutableContainers 
                   error:&jsonError]; 
          if (!jsonError) { 
           _allCategories = json; 
           NSLog(@"allcategories - %@",_allCategories); 
          } 
         } 
     }]; 

     [getCategories resume]; 
    } 

    return self; 
} 

然后在视图控制器我执行

- (void)fetchCategories { 
    NSLog(@"before"); 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),^{ 
      CategoriesStore *categories = [CategoriesStore sharedStore]; 
     dispatch_async(dispatch_get_main_queue(), ^(void) { 
      _allDirectories = categories.allCategories; 
      [self.tableView reloadData]; 
      NSLog(@"after"); 
     }); 
    }); 
} 

-fetchCategories在viewDidAppear执行。结果通常是之前,之后然后JSON。显然我想得到的是之前,json在之后。

我也试着用dispatch_group_notify做到这一点,但没有工作。

我该如何得到它的工作?为什么它不等待第一项任务完成? 感谢您的帮助! 问候,阿德里安。

回答

0

我建议来定义CategoriesStore一个专门的方法,从远程服务器获取数据,并采取回调作为参数:

- (void)fetchDataWithCallback:(void(^)(NSArray *allCategories, NSError* error))callback 
{ 

    NSURLSessionDataTask *getCategories = 
     [self.session dataTaskWithURL:categoriesURL 
        completionHandler:^(NSData *data, 
             NSURLResponse *response, 
             NSError *error) { 
         if (error) { 
          NSLog(@"error - %@",error.localizedDescription); 
          callback(nil, error); 
          return; 
         } 

         NSError *jsonError = nil; 

         NSArray *json = 
         [NSJSONSerialization JSONObjectWithData:data 
                 options:NSJSONReadingMutableContainers 
                  error:&jsonError]; 
         if (!jsonError) { 
          _allCategories = json; 
          NSLog(@"allcategories - %@",_allCategories); 
          callback(_allCategories, nil); 
         } else { 
          callback(nil, jsonError); 
         } 
     }]; 

     [getCategories resume]; 
} 

而且你可以在你的ViewController使用它:

- (void)fetchCategories { 
    [[CategoriesStore sharedStore] fetchDataWithCallback:^(NSArray *allCategories, NSError* error) { 
     if (error) { 
      // handle error here 
     } else { 
      _allDirectories = allCategories; 
      [self.tableView reloadData]; 
     } 
    }] 
} 

通过这种方式,您将在数据加载&解析后重新加载您的表格视图。

0

你必须等待重新载入数据,所以你可以做这样的事情,如果你不想等待整个块和公正的获取另一种选择是使用自定义的NSLock

dispatch_sync(dispatch_get_main_queue(), { 
    _allDirectories = categories.allCategories; 
    [self.tableView reloadData]; 
} 
NSLog(@"after"); 
0

我使用@ sgl0v建议的方法,虽然它不是我期望的解决方案。 另一种方法是使用通知中心并监听事件的发生。