我想做以下事情:
1. display loader
2. download database update and reload data
3. hide loader
我的想法是在数据库的更新方法开始和结束时向主视图控制器发送通知,以便视图控制器显示和隐藏加载器。
我担心控制流。我是否可以保证视图控制器会在数据库的更新方法继续之前收到通知并显示加载器?
我想做以下事情:
1. display loader
2. download database update and reload data
3. hide loader
我的想法是在数据库的更新方法开始和结束时向主视图控制器发送通知,以便视图控制器显示和隐藏加载器。
我担心控制流。我是否可以保证视图控制器会在数据库的更新方法继续之前收到通知并显示加载器?
通知在系统中排队,因此不能保证它会立即出现。无论如何,它们通常很快,肯定比数据库上的工作要快。
如果您想 100% 确定,只需在某处设置一个标志,当您收到通知时,检查数据库是否已重新加载。
无论如何,我只是在想,即使在重新加载数据库之后收到通知,因为通知是排队的,所以隐藏加载程序通知会在第一个通知之后立即到来,所以没有什么可担心的。
通常你会希望视图控制器启动更新,所以只要你确保在此之前设置监听器(更新的启动),并且在你的视图控制器完全加载之后你应该没问题。(即在 viewDidAppear 中开始更新)
你可以像下面这样实现它:
- (IBAction)updateDatabase:(id)sender {
__block MyController* blockSelf = self;
__weak MyController* weakSelf = self;
[self startBusyIndicator];
[self asyncDownloadDatabase:^(id result, NSError*error) {
if (error == nil) {
[blockSelf.database updateWithData:result];
}
blockSelf = nil;
MyController* strongSelf = weakSelf;
if (strongSelf) {
dispatch_async(dispatch_get_main_queue(), ^{
[strongSelf reloadData];
[strongSelf stopBusyIndicator];
});
}
}];
}
使用blockSelf
保证控制器保持活动状态,直到asyncDownloadDatabase
完成并更新数据库。假设更新过程可以在任何线程上执行。
weakSelf
只会在 blockSelf 设置为 nil 之后立即变为零,如果这是对控制器的最后一次引用 - 例如,用户已切换到另一个视图。在这种情况下,不会更新任何视图——它们已经被释放。否则,如果控制器仍然存在,则视图将被更新。