我在应用中遇到线程问题。这是我第一次使用AFNetworking和Parse。问题是我要调用这两个功能,他们都需要完成才能进入下一个segue。
这是我的代码。第一个块用于使用AFHTTP的网络请求,第二个块用于解析请求。
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"foo": @"bar"};
[manager POST:@"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
PFQuery *query = [PFQuery queryWithClassName:@"dependant"];
[query whereKey:@"parentID" equalTo:[masterAccount getObjectID]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
for (PFObject *dependant in objects) {
//do some stuff with parse object here
}
[self performSegueWithIdentifier: @"MySegue" sender: self];
}];
据我所知,这两个都是在自己的线程中创建和运行,以免阻止gui,这是正确的吗?我将在何处移动segue调用(当前位于Parse块的末尾),以便在这些请求的 完全完成之前不会调用它?
答案 0 :(得分:0)
您可以使用Grand Central Dispatch解决此问题,更具体地说,#34; Dispatch Groups"
分组块允许聚合同步。你的申请 甚至可以提交多个块并跟踪它们是否全部完成 虽然他们可能会在不同的队列上运行。这种行为可以 在完成所有指定任务之前无法取得进展时很有帮助 已经完成了。
答案 1 :(得分:0)
这里发生了什么:
// Runs 1st
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"foo": @"bar"};
[manager POST:@"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
// Runs 3rd
NSLog(@"JSON: %@", responseObject);
// Run your code here, or trigger your code here
PFQuery *query = [PFQuery queryWithClassName:@"dependant"];
[query whereKey:@"parentID" equalTo:[masterAccount getObjectID]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
for (PFObject *dependant in objects) {
//do some stuff with parse object here
}
[self performSegueWithIdentifier: @"MySegue" sender: self];
}];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
// Runs 2nd
答案 2 :(得分:0)
我认为这就是你想要的......
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"foo": @"bar"};
__weak __typeof(self) weakSelf = self;
[manager POST:@"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
PFQuery *query = [PFQuery queryWithClassName:@"dependant"];
[query whereKey:@"parentID" equalTo:[masterAccount getObjectID]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
__strong __typeof(self) strongSelf = weakSelf;
for (PFObject *dependant in objects) {
//do some stuff with parse object here
}
[strongSelf performSegueWithIdentifier: @"MySegue" sender: self];
}];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
此代码按顺序运行每个异步请求,这是最简单的方法。
答案 3 :(得分:0)
执行此操作的一种简单方法是使用单独的对象,例如ResourceState。给它两个属性,一个用于gotJsonData,一个用于gotParseData。在完成处理程序中,只需在ResourceState中调用一个方法,该方法更新相应的属性(json或parse),如果两个属性都设置为success,则触发segue。我不会尝试使用块内块方法 - 它的代码较少,但可能使代码难以维护。
你在这里遇到的根本问题是你需要在'模型'之间进行清晰的分离。和'查看控制器'。我通常工作的方式是让模型完成所有工作,包括网络请求,当它知道需要UI端更新时,它会发送一个NSNotification,主线程上的UI会监听,然后更新UI。