一个具有多个线程和不同viewcontrollers的任务

时间:2015-07-27 10:50:14

标签: ios objective-c json multithreading

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

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

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);
    }
}
}

感谢您的帮助和建议!

2 个答案:

答案 0 :(得分:0)

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

<div class="translate">
        <form method="post">
            <input type="text" name="input_element" id="target" placeholder="Type Germen word"> 
        </form>
        <br>
        <div class="inpt-el"></div><br>
        <div class="translate_control" lang="de"></div>
    </div>   

 <script>
    function googleSectionalElementInit() {
      new google.translate.SectionalElement({
        sectionalNodeClassName: 'translate',
        controlNodeClassName: 'translate_control',
        background: '#f4fa58'
      }, 'google_sectional_element');
    }
    </script>
    <script src="//translate.google.com/translate_a/element.js?cb=googleSectionalElementInit&ug=section&hl=en"></script>
    <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
    <script>
    $( "#target" ).keyup(function() {
      $('.inpt-el').text($(this).val());
    });
    </script>

答案 1 :(得分:0)

我做了什么来修复“这个问题是我使用了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类传递数据是不可能的,因为属性rearViewController具有对此控制器的自己的引用。