【问题标题】:One task with multiple threading and different viewcontrollers具有多线程和不同视图控制器的一项任务
【发布时间】:2015-08-03 17:42:51
【问题描述】:

我仍然面临 iOS 上的多线程问题。基本上我想做的是在 MainViewController 中获取 json(当应用程序启动时),然后用这些数据填充左侧菜单(SWRevealViewController)。

但是让我们考虑一下网速低的情况,当用户显示菜单并且数据不是来自 MainViewController 时。显然我正在从两个控制器中获取 JSON。我不知道如何让 Sidebar 等待该数据,直到 MainViewController 完成获取?

MainViewController 调用

[[CategoriesStore sharedStore] fetchDataWithCallback:^(NSArray *allCategories, NSError* error) {

}];

从异步块内的 SidebarViewController 调用

[[CategoriesStore sharedStore] fetchDataWithCallback:^(NSArray *allCategories, NSError* error) {
    if (error) {
    } else {
        //[self.tableView beginUpdates];
        blockSafe.allDirectories = allCategories;
        [blockSafe.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade];

    }
}];

CategoriesStore 获取 json(单例模型)

+(instancetype)sharedStore {
static CategoriesStore *sharedStore = nil;
static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{
    sharedStore = [[self alloc] initPrivate];


});

return sharedStore;

}

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

if (self) {
    [self sessionConf];
    _allCategories = nil;
}

return self;
}

- (void)fetchDataWithCallback:(void(^)(NSArray *allCategories, NSError* error))callback {
NSLog(@"CategoriesStore - %@",self.description);
@synchronized(self) {
    if (!_allCategories) {
        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(@"categories fetched");
                            callback(_allCategories, nil);
                        } else {
                            callback(nil, jsonError);
                        }
                    }];

        [getCategories resume];
    } else {
        callback(_allCategories,nil);
    }
}
}

感谢您的帮助和建议!

【问题讨论】:

  • 有人吗?请。我敢打赌,这是一件容易而棘手的事情。另一种解决方案是回调侧边栏视图控制器,但它不适用于 SWRevealController。

标签: ios objective-c json multithreading


【解决方案1】:

你可以这样做: dispatch_group_t group_t = dispatch_group_create();

    dispatch_group_async(group_t, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //do the first thing
    });

    dispatch_group_async(group_t, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //do the second thing
    });

    dispatch_group_notify(group_t, dispatch_get_main_queue(), ^{
        //update UI
    });

【讨论】:

  • 感谢@Burning 的回复,但它不适用于不同的 ViewController(类)
【解决方案2】:

我做了什么来解决“这个问题是我使用了 SWRevealViewController rearViewController 属性。

当我设置侧边栏以在 MainViewController 中显示(因此在委托中)时,会回调 fetchJSON。

-(void)sideBarSetup {
    ....... your initialization for RevealSideBar........
    [self fetchJSON];
}

fetchJSON 的主体

-(void)fetchJSON {
    SidebarViewController *svc = (SidebarViewController *)self.revealViewController.rearViewController;
    [svc fetchAll];
}

然后在 SidebarViewController 中。

dispatch_group_t fetchingGroup = dispatch_group_create();

dispatch_group_enter(fetchingGroup);

[[CategoriesStore sharedStore] fetchDataWithCallback:^(NSArray *allCategories, NSError* error) {
    if (error) {
        // handle error here
    } else {
        blockSafe.allDirectories = allCategories;
        [blockSafe.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade];

    }
}];

[[LinksStore sharedStore] fetchDataWithCallback:^(NSArray *allLinks, NSError* error) {
    if (error) {
        // handle error here
    } else {
        blockSafe.allLinks = allLinks;
        [blockSafe.tableView reloadSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationFade];
    }
}];

dispatch_group_leave(fetchingGroup);

dispatch_group_notify(fetchingGroup, dispatch_get_main_queue(), ^{
    [self.tableView endUpdates];
});

当然,您必须在头类文件中添加接口方法。

在这种情况下,不可能通过 SidebarViewController 类的初始化来传递数据,因为属性后视图控制器对这个控制器有自己的引用。

【讨论】:

    猜你喜欢
    • 2019-01-08
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多