无法在块外使用数组

时间:2014-07-14 09:23:09

标签: ios objective-c objective-c-blocks

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
}

3 个答案:

答案 0 :(得分:3)

你应该知道的是执行流程。

在古老的程序中,代码执行总是从上到下。无论如何,这个前提很久以前就被打破了。现代程序使用多个组件构建,例如函数,类和块(闭包),程序并不总是从上到下流动。 (好吧,虽然它主要是这样做)

块(闭包)是这个非顺序程序之一。将代码块保存到变量中以便稍后执行。关键是,代码块在定义时没有被执行。

你在这里做的是:

  1. 制作一个空数组。
  2. 创建并传递一个代码块,将数组填充到方法中。
  3. 使用NSLog打印数组。
  4. 在#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

    }];
}