2013-04-28 49 views
1

我已經編寫了一些代碼來修改正在成爲「reverseGeocodeLocation」方法一部分的completionblock處理程序中的實例變量。下面是代碼首先:從完成塊內修改實例變量

- (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完成塊內。

只要我嘗試訪問完成塊之外的實例變量,就會收到一條錯誤消息,表示數組中沒有值。我錯過了一些重要的東西嗎?

我已經讀過「reverseGeocodeLocation」是一個異步消息,當我嘗試讀取實例var時,還無法完成。但在我看來,不應該這樣,因爲完成塊已經被調用,我可以在完成塊內記錄數組的條目。

我不知道現在該做什麼。我有這樣的感覺,那就是一個非常簡單的解決方案,我現在幾個小時完全沒有得到它。也許你可以幫我一把嗎?

謝謝

+0

'tableViewRows'的定義是什麼?它強大/保留?如果沒有,它會在你嘗試使用它之前被釋放。 – Wain 2013-04-28 07:31:30

+0

嗨! jep ...它是@property(nonatomic,strong)NSMutableArray * tableViewRows; – sesc360 2013-04-28 07:36:21

+0

確保在設置數據和調用表格視圖之前切換回主線程。或者至少使屬性成爲原子並在主線程上調用表。 – Wain 2013-04-28 07:42:07

回答

0

所以看起來你告訴你總是有它的5行表視圖,但它可能不是真的。你應該問self.tableViewRows.count實際計數。鑑於此,我認爲當你嘗試重新加載自己時,你會在表視圖的第一次加載時崩潰,但是tableViewRows是空的。

另外,你應該將你的tableView分配給viewDidLoad屬性

+0

我也試過,以及..但是當我這樣做時,整個應用程序是freezin'。並沒有顯示任何表格。但更重要的是,該應用程序不再響應。數據似乎都在那裏。但只在INSIDE完成塊內。它沒有設法將代碼複製到實例var並保留。 – sesc360 2013-04-28 08:01:38

+0

我不認爲它沒有響應,將你的表init行改爲'[[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]',這樣你的框架是正確的,並且表是純的,所以你可以看到滾動工作 – 2013-04-28 08:10:12

+0

剛剛嘗試過..你在這部分是正確的..該應用程序是響應。但我發現,如果我嘗試在reverseGeocodeLocation方法內記錄「dataArray」變量,並在完成塊的右括號後面放置NSLOG,則該數組中沒有任何內容。即使它被分配爲__block變量。所以內容只在完成塊內部可見。這對我來說似乎很奇怪。 dataArray變量應該由完成塊填充數據,不是嗎?這就是爲什麼我的實例var也是空的!? – sesc360 2013-04-28 08:16:00