我是来自 EmberJS 的 JS 背景的 iOS 开发新手。我想将我的 EmberJS 应用程序移植到 iOS 应用程序。因此,我想在我的 iOS 应用程序中使用类似的结构。由于 EmberJS 大量使用了 Promise,我在 iOS 上搜索了类似的东西并偶然发现了 ReactiveCocoa。在 ReactiveCocoa 的介绍中说,这个框架可以用来实现 Promises。我试过了,但它不能正常工作。我想从一个非常简单的例子开始:
- 发出异步网络请求(填充 UITableViewController)。从此方法返回一个承诺。
- 订阅此承诺并在完成后重新加载 TableView。
我想这样做,因为在成功加载数据后我将不得不执行几件事。我的方法基本上有效,但我遇到了以下问题:
- 请求完成后,我的 TableView 不会立即重新加载。
subscribeCompleted
请求完成后,我立即在我的日志中看到了日志语句。但是 TableView 保持空白。- TableView 在等待几秒钟后加载数据。
- 如果我在看到 Log 输出后开始滚动 TableView,则 TableView 会突然加载。
我怀疑这可能会发生,因为我正在后台线程中获取数据。我认为 promise ( subscribeCompleted
) 的解析也可能发生在后台线程中,而 Cocoa Touch 可能不喜欢这样。我对吗?但如果是这种情况,我应该如何实现承诺?
我希望你能帮助我开始使用 ReactiveCocoa。谢谢!:-)
更新:
我设法通过将 to 包装reloadData
在 a 中来修复它,dispatch_async(dispatch_get_main_queue(), ^{...
但我仍然不确定这是最好的方法还是 ReactiveCocoa 推荐的方法。所以我仍然渴望听到一些答案:-)
// this method wants to use the promise
- (void) loadDataAndPerformActionsAfterwards{
RACSignal *signal = [self fetchObjects];
[signal subscribeCompleted:^{
NSLog(@"Entered subscribeCompleted block signal!");
NSLog(@"Number of objects: %i", self.objects.count);
[self.tableView reloadData];
}];
}
// this method returns a promise. I omitted some parts but it shows basically how i go about resolving the promise.
- (RACSignal*) fetchMoviesForCurrentFormState{
return [RACSignal createSignal:^RACDisposable*(id<RACSubscriber> subscriber) {
NSLog(@"RAC createSignal Block called");
NSString *requestURL = @"...";
NSURL *urlObj = [NSURL URLWithString: requestURL];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL: urlObj];
if(data){
[self performSelectorOnMainThread:@selector(fetchedData:)
withObject:data waitUntilDone:YES];
[subscriber sendCompleted];
}else{
// Not implemented yet: handle the error case
[subscriber sendCompleted];
}
});
// actually i do not know yet what i should return here. Copied from a basic example.
return nil;
}];
}