Hai我在块中编写代码来获取车辆的地标。我的问题是我将地标存储在NSMutablearray
内,但我无法访问块外的数组。请建议我克服这个问题。提前致谢。我的代码如下......
CLLocation *someLocation=[[CLLocation alloc]initWithLatitude:latitude longitude:longitude];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:someLocation completionHandler:^(NSArray *placemarks, NSError *error) {
if ([placemarks count] > 0) {
NSDictionary *dictionary = [[placemarks objectAtIndex:0] addressDictionary];
addressOutlet=[dictionary valueForKey:@"Street"];
City=[dictionary valueForKey:@"City"];
State=[dictionary valueForKey:@"State"];
if (addressOutlet!=NULL&&City!=NULL)
{
SubTitle=[NSString stringWithFormat:@"%@,%@,%@",addressOutlet,City,State];
}
else if (addressOutlet==NULL&&City!=NULL)
{
SubTitle=[NSString stringWithFormat:@"%@,%@",City,State];
}
else if (addressOutlet!=NULL&&City==NULL)
{
SubTitle=[NSString stringWithFormat:@"%@,%@",addressOutlet,State];
}
else if(addressOutlet==NULL&&City==NULL&&State!=NULL)
{
SubTitle=[NSString stringWithFormat:@"%@",State];
}
else if (addressOutlet==NULL&&City==NULL&&State==NULL)
{
SubTitle=[NSString stringWithFormat:@"%@",@""];
}
[storeArray addObject:SubTitle];
}
NSLog(@"%@",storeArray);// I can access here
}];
NSLog(@"%@",storeArray);// Here it shows empty array
}
答案 0 :(得分:3)
你应该知道的是执行流程。
在古老的程序中,代码执行总是从上到下。无论如何,这个前提很久以前就被打破了。现代程序使用多个组件构建,例如函数,类和块(闭包),程序并不总是从上到下流动。 (好吧,虽然它主要是这样做)
块(闭包)是这个非顺序程序之一。将代码块保存到变量中以便稍后执行。关键是,代码块在定义时没有被执行。
你在这里做的是:
NSLog
打印数组。在#2点,代码块不会立即执行,但会在操作完成时执行。然后,当您打印它时,数组尚未填充,然后它只打印一个空数组。
你应该对待在#2定义的代码块将在未来未知的时间点执行,你真的无法控制时间。这是异步编程的一个不好的地方,也是你需要熟悉的东西。
答案 1 :(得分:0)
这是因为阻止。
您收集的数组是在进程发生一段时间后执行的异步执行。
但外部日志在完成和收集数据之前执行,因此它不返回任何值并且不打印任何内容
[geocoder reverseGeocodeLocation:someLocation completionHandler:^(NSArray *placemarks, NSError *error) {
//Some process collecting values in array
[storeArray addObject:SubTitle];
}
NSLog(@"%@",storeArray);// I can access here
//Do everything here after data gets populated
[tableview reloadData];
}];
//Here no values exist since execuion of this happens before the inner block execution
}
答案 2 :(得分:0)
那是因为reverseGeocodeLocation:completionHandler
方法是异步执行的,在你的情况下,第二个NSLog
先前被调用,然后是第一个在完成块中。
请检查:Obj-C blocks
--------- EDIT -----------
您必须在完成块中继续逻辑(即第一次调用NSLog时)。
-(void)downloadLocations:(void(^)(void))callback
{
storeArray = [[NSMutableArray alloc] init];
//...
for(int f=0;f<Vehicle_No.count;f++){
//...
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:someLocation completionHandler:^(NSArray *placemarks, NSError *error) {
//...
NSLog(@"%@",storeArray);// I can access here
if (callback) {
callback();
}
}];
}
}
- (void)foo
{
//...
[self downloadLocations:^{
//do something here with storeArray
}];
}