我正在尝试在tableview中输入正确返回的JSON的结果。 问题是我只能访问返回信息的块内的数据,甚至可以将结果分配给实例变量。 我的代码如下:
NSURL *url = [NSURL URLWithString:@"http://www.my_url.com.br/app/?type=list&info=15,16&lat=some_data&long=some_data"];
ASIHTTPRequest *_request = [ASIHTTPRequest requestWithURL:url];
ASIHTTPRequest *request = _request;
request.requestMethod = @"POST";
[request addRequestHeader:@"Content-Type" value:@"application/json"];
[request setDelegate:self];
[request setCompletionBlock:^{
NSString *responseString = [request responseString];
NSLog(@"Response: %@", responseString);
NSDictionary *root = [NSJSONSerialization JSONObjectWithData:request.responseData options:0 error:nil];
self.data = [root objectForKey:@"listing"];
NSLog(@"Data returned: %@", data); //Everything works well. The data returned is printed correctly
}];
[request setFailedBlock:^{
NSError *error = [request error];
NSLog(@"Error: %@", error.localizedDescription);
}];
[request startAsynchronous];
NSLog(@"Data only: %@", data); //At this point, the "data" content is nil
这是我的“ListDataController.h”文件定义:
@interface ListDataController : UITableViewController{
ApplicationCell *tmpCell;
NSArray *data;
UILabel *status ;
UINib *cellNib;
}
@property (nonatomic, retain) IBOutlet ApplicationCell *tmpCell;
@property (nonatomic, retain) NSArray *data;
JSON返回: 数据自我:( { Icon =“Baseball.png”; 名字=棒球; NumRatings = 106; 价格=“2.98美元”; 出版商=“Super Sportz,Inc。”; 评级=“3.5”; }, { Icon =“Checkers.png”; 名字= Checkers; NumRatings = 87; 价格=免费; Publisher =“Gameitoids,Inc。”; 评级= 4; } )
问题是:为什么我不能访问块外的实例变量“data”,甚至为它分配json的结果?
答案 0 :(得分:1)
您可以访问该区域外的data
,但会将其设置为nil
。您可能正确设置data
,而不是在您想到的那一刻。
当您执行最终日志时,完成块尚未运行。请求是异步,这意味着完成块将在将来的某个时刻执行。这是使用块时理解的关键概念。
<强>更新强>:
要在检索数据后对其进行处理,您可以从完成块中调用所需的数据:
[request setCompletionBlock:^{
NSString *responseString = [request responseString];
NSLog(@"Response: %@", responseString);
NSDictionary *root = [NSJSONSerialization JSONObjectWithData:request.responseData options:0 error:nil];
self.data = [root objectForKey:@"listing"];
NSLog(@"Data returned: %@", data); //Everything works well. The data returned is printed correctly
[self handleData:self.data]; // you would have to define this method your self
}];
要考虑的一件事是,如果要基于self.data
更新UI,则需要确保在主线程上执行handleData
。
一些链接:
答案 1 :(得分:0)
这里发生的是你的日志
NSLog(@"Data only: %@", data); //At this point, the "data" content is nil
将在获取数据之前执行。您正在使用异步请求使用块,即执行将在单独的线程上发生而不影响主线程执行
并且在单独的线程完成时,完成块被执行.Hence响应仅在此时加载到数据中
为了更好的理解
您可以看到日志上的执行发生在完成块之前
编辑:
您可以在分配给data
[request setCompletionBlock:^{
NSString *responseString = [request responseString];
NSLog(@"Response: %@", responseString);
NSDictionary *root = [NSJSONSerialization JSONObjectWithData:request.responseData options:0 error:nil];
self.data = [root objectForKey:@"listing"];
NSLog(@"Data returned: %@", data); //Everything works well. The data returned is printed correctly
//DO here WHATEVER you want to do after getting response
//eg:
[table reloadData]
}];
获取所有数据时的请求将执行完成块。所以在获得响应后您想要做的任何事情都可以在完成块中完成
答案 2 :(得分:0)
答案 3 :(得分:0)
NSLog(@"Data returned: %@", data); //Everything works well. The data returned is printed correctly
精细。你有什么问题?这是完成块。它在收到所有数据时执行。在该最佳情况下,在该时间点之前对数据的任何访问将最终为零,或者在最坏的情况下最终为out / wron /不可预测的数据。