在AppDelegate中的reloadData之后未调用cellForRowAtIndexPath

时间:2015-05-11 20:31:38

标签: ios objective-c iphone uitableview reloaddata

我一直在寻找几个小时,尽管有相似的帖子,我还没有找到解决问题的方法。我正在创建一个应用程序(目前开始)使用startMonitoringSignificantLocationChanges不断更新用户位置。我有一个自定义的viewcontroller LocationsViewController,它只是一个用于显示用户前往的每个位置的tableview。在我的didUpdateLocations

- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations
{
    _currentLocation = _locationManager.location;
    [_locations addObject:_currentLocation];
    [_locationsViewController.tableView reloadData];
}

然后在LocationsViewController的numberOfRowsInSection方法中,我有代码:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    AppDelegate * delegate = [AppDelegate sharedInstance];
    NSLog(@"%lu", (unsigned long)[delegate.locations count]);
    return [delegate.locations count];
}

现在我在LocationsViewController中实例化了AppDelegate,如此:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    sharedInstance              = self;
    _datahub                    = [[Datahub alloc] init];
    _locations                  = [[NSMutableArray alloc] init];
    _locationManager            = [[CLLocationManager alloc] init];
    _locationManager.delegate   = self;

    UIStoryboard * storyboard   = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

    _locationsViewController    = (LocationsViewController*) [storyboard instantiateViewControllerWithIdentifier:@"locationsViewController"];
    _timePickViewController     =  (TimePickViewController*) [storyboard instantiateViewControllerWithIdentifier:@"timePickViewController"];


    if ([_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        [_locationManager requestAlwaysAuthorization];
    }

    [_locationManager startMonitoringSignificantLocationChanges];
    return YES;
}

LocationsViewController的{​​{1}}方法中,首次实例化numberOfRowsInSection时,delegate.locations的计数为0。但是,在调用LocationsViewController之后,数组didUpdateLocations将填充1个位置。然后调用delegate.locations方法,当再次调用reloadData时,它返回1.如果方法返回1,则应立即调用numberOfRowsInSection;但由于某种原因,它没有被调用。我想知道是否有人知道,1。我的代码可能出现什么问题(我不认为它与任何格式或tableview设置有关,因为我使用了故事板),我有cellForRowAtIndexPath和{{ 1}}都设置为dataSource,我也尝试实现delegate方法。无论我做什么,我都没有运气。调用self.tableView后,除heightForRowAtIndexPath外,将调用所有正确的方法。任何可能出错的建议或导致都会很棒。如果它有帮助,这里有更多代码,谢谢: LocationsViewController.m

reloadData

AppDelegate.m

cellForRowAtIndexPath

1 个答案:

答案 0 :(得分:0)

@ rdelmar的评论是问题的核心。在您的app委托中,您将实例化LocationsViewController,然后再对其进行任何操作。该视图控制器永远不会出现在屏幕上,永远不会做任何事情。

一般来说,除了初始设置和处理应用委托方法之外,让应用委托管理任何其他内容都是不好的。您应该让视图控制器创建一个位置管理器对象,或者设置一个单独的位置服务对象来执行此操作。

进入视图控制器并直接操作它的视图对象也是一个非常的坏主意。如果您需要一个视图控制器来更新其中一个视图,那么您应该添加一个外部对象调用的方法,该方法将根据需要更改视图。

使视图控制器管理位置管理器本身是迄今为止最简单的解决方案,尽管它有局限性。只有那个视图控制器关心位置服务,这种方法才真正有效。

如果您的应用中有其他对象(视图控制器等)关心位置信息,您应该创建一个单独的对象来管理位置更新。在这种情况下,您应该使用委托进行设置,或者在更新可用时为其提供位置更新块。如果您希望同时通知应用中的多个视图控制器,您可能希望使用通知管理器发送自定义位置更新通知。

您可能希望将位置服务对象设为单例。这样,您的视图控制器可以获取位置服务对象的单个实例,并将它们自己设置为删除/设置它们的处理程序块作为最活跃的处理程序块。