从完成块内修改实例变量

时间:2013-04-28 07:16:01

标签: iphone objective-c block instance-variables

我编写了一些代码来修改一个实例变量,该实例变量来自completionblock处理程序,该处理程序是“reverseGeocodeLocation”方法的一部分。首先是代码:

- (void)reverseGeocodeLocation:(CLLocation *)aLocation {
    CLGeocoder *geoCoder = [[CLGeocoder alloc] init];
    __block __strong NSArray *dataArray;

    [geoCoder reverseGeocodeLocation:aLocation completionHandler:^(NSArray *placemarks, NSError *error) {
        if (error == nil && [placemarks count] > 0) {
            CLPlacemark *placemark = [placemarks lastObject];
            CLLocation *userLocation = [placemark location];

            NSString *latitude = [NSString stringWithFormat:@"Lat. %f degrees", userLocation.coordinate.latitude];
            NSString *longitude = [NSString stringWithFormat:@"Long. %f degrees", userLocation.coordinate.longitude];
            NSString *altitude = [NSString stringWithFormat:@"Alt. %f m", userLocation.altitude];
            NSString *speed = [NSString stringWithFormat:@"Speed %f m/s", userLocation.speed];
            NSString *course = [NSString stringWithFormat:@"Course %f degrees", userLocation.course];

            dataArray = @[latitude, longitude, altitude, speed, course];

        // The data array is perfectly populated!!

            NSLog(@"Just checking... %@", dataArray);

        dispatch_sync(dispatch_get_main_queue(), ^{
            self.tableViewRows = [NSMutableArray arrayWithArray:dataArray];
            [self.tableView reloadData];
        });

        } else {
            NSLog(@"%@", error.debugDescription);
        }
    }];

}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {

    CLLocation *currentLocation = [locations lastObject];
    [self reverseGeocodeLocation:currentLocation];
}

这是tableView的代码:

#pragma mark -
#pragma mark TabeView

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    //
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 5;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
        cell.accessoryType = UITableViewCellAccessoryNone;
        cell.textLabel.text = [self.tableViewRows objectAtIndex:indexPath.row];
    }

    return cell;
}

VC的其余部分:

- (id)init {
    self = [super init];
    if (self) {

        if ([CLLocationManager locationServicesEnabled]) {
            self.locationManager = [[CLLocationManager alloc] init];
            self.locationManager.delegate = self; // location manager delegate
            self.locationManager.distanceFilter = 1000;
            [self.locationManager startUpdatingLocation];
        }

        // Create the Rows Array for the TableView
        self.tableViewRows = [[NSMutableArray alloc] init];
    }
    return self;
}

-(void)viewDidLoad {
    [super viewDidLoad];

    // Create the TableView
    UITableView *table = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStyleGrouped];
    table.dataSource = self;
    table.delegate = self;
    [self.view addSubview:table];
}

嗯......正如你所看到的,我想填充实例变量“tableViewRows”。临时数组“dataArray”的数量非常合适!显示所有值。并且方法中的实例变量的填充也正常工作!但只有INSIDE完成块。

一旦我尝试访问完成块之外的实例变量,我就会收到一条错误消息,表明数组中没有值。我错过了一些重要的东西吗?

我已经读过,当我尝试读取实例var时,“reverseGeocodeLocation”是一个无法完成的异步消息。但在我看来应该不是这种情况,因为已经调用了完成块,我可以在完成块内部记录数组的条目。

我不知道现在该做什么。我有一种感觉,这是一个非常简单的解决方案,我现在完全没有得到它好几个小时。也许你可以帮助我?

谢谢

1 个答案:

答案 0 :(得分:0)

所以看起来你正在告诉表视图,你总是中有5行,但它可能不是真的。您应该询问self.tableViewRows.count实际计数。鉴于此,我认为你在表视图的第一次加载时会崩溃,当它试图重新加载自己时,但tableViewRows是空的。

另外,您应该将viewView分配给viewDidLoad

中的属性