当我在下面的内部记录我的数组self.userData时,将填充该数组。
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableDictionary *viewParams = [NSMutableDictionary new];
[viewParams setValue:@"u000" forKey:@"view_name"];
[DIOSView viewGet:viewParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.userData = [responseObject mutableCopy];
NSLog(@"userData = %@", self.userData);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Failure: %@", [error localizedDescription]);
}];
但是,当我尝试获取填充的数据并在这些括号外(例如下面)使用它时,数组是空的?我该如何解决这个问题?
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableDictionary *viewParams = [NSMutableDictionary new];
[viewParams setValue:@"u000" forKey:@"view_name"];
[DIOSView viewGet:viewParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.userData = [responseObject mutableCopy];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Failure: %@", [error localizedDescription]);
}];
self.userBio.text = self.userData[0][@"userbio"];
NSLog(@"userData = %@", self.userData);
答案 0 :(得分:2)
在两个示例中都填充了数组。
由于AFHTTPRequestOperation
异步工作,因此块在viewDidLoad
完成后返回数据,因此在第二个示例中执行NSLog
行之后。
答案 1 :(得分:2)
您误解了像AFHTTPRequestOperation这样的异步方法是如何工作的。重点是这样的方法在请求被发送到远程服务器之前立即返回。
任务完成后,它会调用完成块。一旦数据可用,您想要做的任何工作都应该在完成块内。
我不记得AFNetworking的完成方法是在主线程还是后台线程上运行。咨询他们的文档。如果从后台运行完成块,则需要在调用dispatch_async(dispatch_get_main_queue())时进行UI更改。
看一下文档,看起来你正在使用的AFHTTPRequestOperation
类默认调用主队列上的完成块,除非你通过设置successCallbackQueue
属性指定不同的队列。
因此,除非您设置了successCallbackQueue
,否则无需担心在调用dispatch_async()时包含UI操作。
答案 2 :(得分:0)
问题是,您成功运行块是异步调度的。也就是说,它发生在另一个线程上。因此,当您尝试在括号后访问您的userData时,成功块中的代码没有机会执行。 最简单的方法是使用信号量。但是"修复"的含义取决于您的具体情况 - 您收到的数据以及您将使用的数据。你可以从括号内调用一些方法,你可以发布NSNotification。正如我所说,你应该考虑使用最好的方式来完成你的特定任务
答案 3 :(得分:0)
在您的AFNetworking成功阻止中添加如下内容:
[[NSNotificationCenter defaultCenter] postNotificationName:@"myDataSuccededLoading" object:nil];
在异步调用通知观察器之前添加viewDidLoad,如下所示:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSuccess) name:@"myDataSuccededLoading" object:nil];
添加一个void方法来处理成功(handleSuccess)。也许您应该考虑重复上述(使用不同的通知字符串)来处理失败......
答案 4 :(得分:0)
尝试这样的事情
self.userBio.text = [self.userData[0]valueForkey@"userbio"];