Ios 如何将数据保留在块代码之外?
我正在尝试使用AFNetworking和MJ扩展解析JSON链接。 请参阅代码中的注释Ios 如何将数据保留在块代码之外?,ios,afnetworking-3,Ios,Afnetworking 3,我正在尝试使用AFNetworking和MJ扩展解析JSON链接。 请参阅代码中的注释 - (void)viewDidLoad { [super viewDidLoad]; NSString *apiURL = @"https://api.forecast.io/forecast/APIKEY/Lat,Long"; NSURL *URL = [NSURL URLWithString:apiURL]; AFHTTPSessionManage
- (void)viewDidLoad {
[super viewDidLoad];
NSString *apiURL = @"https://api.forecast.io/forecast/APIKEY/Lat,Long";
NSURL *URL = [NSURL URLWithString:apiURL];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:URL.absoluteString parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) {
weatherDict = (NSDictionary *)responseObject;
weather = [WeatherClasses mj_objectWithKeyValues:weatherDict];
//----------------------
//when i set the label.text here, the label shows whatever the JSON value is
self.apparentTemperature.text = [NSString stringWithFormat:@"%f", weather.currently.apparentTemperature];
NSLog(@"Temp: %f", weather.currently.apparentTemperature);
} failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
//--------------------------
//but if i set the label here, its always 0 (or nil for NSString)
self.apparentTemperature.text = [NSString stringWithFormat:@"%f", weather.currently.apparentTemperature];
}
在成功块中,我的字典有数据,但当我退出成功块时,字典为零。如何使字典在AFHTTPSessionManager中设置后不为零
使用块不起作用。在将weatherDict从块代码中删除时使用块关键字。块是异步的,这意味着
self.apparentTemperature.text=[NSString stringWithFormat:@“%f”,weather.Current.apparentTemperature]代码>可能会在块之前执行,其中设置了weather
这就是为什么self.apparentTemperature.text
总是nil
在块之外的原因
要解决这个问题,只需调用一个函数,在该函数中,您将UI元素设置在块的末尾(但在块内),这样它将在执行块后被调用
//但是如果我在这里设置标签,它总是0(对于NSString是nil)
这是因为代码在网络请求完成之前运行,所以数据不存在。当您将块传递到异步方法(如网络调用)中时,块通常会在发出调用的方法退出后执行
使用__块不起作用
不足为奇<代码>\u块
确保这样标记的变量本身在块内使用,而不是在块的上下文中复制,但它不会使数据更快地返回
这里正确的解决方案是在完成块中为请求设置标签——这就是完成块的用途
如何将数据保留在块代码之外
不要尝试——没有理由不在块内设置变量。您可以使用信号量:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:URL.absoluteString parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) {
...
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
self.apparentTemperature.text = [NSString stringWithFormat:@"%f", weather.currently.apparentTemperature];
但我认为情况并非如此。正如人们所说,正确的方法是异步的
只需将代码放在块后面的标签上,或者根本不包含它。此代码的唯一目的是在不调用块时设置默认值
一旦您收到服务器的响应,您的块将被调用,您应该将您的逻辑放在其中,就像现在一样。我使用了
@interface ViewController(){uuuu block WeatherClasses*weather;\uu block NSDictionary*weatherDict;}@end
并且标签仍然显示0这在ViewController.m中