【问题标题】:Why can't I reload my table为什么我不能重新加载我的表
【发布时间】:2013-10-05 18:11:50
【问题描述】:

我是 iOS 开发和 UITableViews 的新手。

我的问题是我正在使用来自外部服务器的数据填充我的 UITableView,但由于多线程,它不会等到数据到达后才加载表格视图。

我目前的想法是在数据加载时重新加载表格视图。

之前在同一个类 DailyBreakdown.c 中,我使用以下代码重新加载表格视图:

-(void)viewWillAppear:(BOOL)animated
{

    [[self class] getAllActivities];

    [super viewWillAppear:animated];
    [self makeObjects];
    [self.tableView reloadData];
}

所以在我的数据加载(使用 Restkit)时的回调中,我尝试再次调用 [self.tableView reloadData],但出现错误:

'struct objc_class'的定义必须从模块中导入 'ObjectiveC.runtime' 之前是必需的

Objective-C 指针类型 'Class' 到 C 指针的隐式转换 type 'struct objc_class *' 需要桥接演员表

这是我从 API 返回 Activity 对象的方法:

+(NSArray *)getAllActivities{

    if (allActivities == nil) {
        // Load the object model via RestKit
        //allActivities = [[NSMutableArray alloc] initWithObjects:@"Workout", @"Baked cake", @"Read for HR", nil];
        allActivities = [[NSMutableArray alloc] init];
        RKObjectManager *objectManager = [RKObjectManager sharedManager];

        [objectManager getObjectsAtPath:@"/activities"
                             parameters:nil
                                success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                                    //allActivities =  [mappingResult array];
                                    allActivities = [NSMutableArray arrayWithArray: [mappingResult array]];
                                    [[self class] makeObjects];

                                    /*** THIS LINE IS THE PROBLEM **/
                                    [self.tableView reloadData];
                                }
                                failure:^(RKObjectRequestOperation *operation, NSError *error) {
                                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                                                    message:[error localizedDescription]
                                                                                   delegate:nil
                                                                          cancelButtonTitle:@"OK"
                                                                          otherButtonTitles:nil];
                                    [alert show];
                                    NSLog(@"Hit error: %@", error);
                                }];
    }

    return allActivities;

}

那么,为什么我不能像以前一样调用 [self.tableView reloadData] 呢?我将如何从我的类方法中执行此操作?

此外,除了重新加载 tableview 之外,还有更好的方法来完成此操作吗?也许线程锁定以便加载视图时 allActivities 不返回 nil ?欢迎任何想法。

谢谢!

【问题讨论】:

    标签: ios objective-c uitableview restkit


    【解决方案1】:

    getAllActivities 是一个类方法,所以你不能从它访问属性和实例方法。最简单的解决方案是使其成为实例方法。在我看来,鉴于您的情况(尝试访问 tableView 属性),此更改将是正确的做法。

    这个问题的另一种解决方案:

    • 您可以向getAllActivities 添加一个block 参数,该参数将在外部服务调用成功完成时调用;在此块中,您将重新加载您的表格
    • 您可以将实例的self 传递给getAllActivities 并使用它来访问tableView

    我注意到的另一件事 - return allActivities; 不会包含上次 RestKit 调用的结果,因为它将在调用完成之前执行。

    【讨论】:

    • 成功了!谢谢!类和实例方法之间的区别暗示了我,所以我必须研究一下。但是现在我的 tableView 正在填充服务器数据,这是一个巨大的里程碑!谢谢!
    • stackoverflow.com/a/11174572/1990236 这里对Objective-C中的实例和类方法有很好的解释
    【解决方案2】:

    您的getAllActivities 方法被定义为类级别的方法(因为它的前缀是加号)。您可能打算做的是定义一个实例级别的方法(用减号代替加号)。

    -(NSArray *)getAllActivities
    

    我注意到的下一件事是,您既没有对调用的结果做任何事情,也没有得到您期望的结果。您的 RKObjectManager 的 getObjectsAtPath 是异步的,并且会立即返回。这意味着 allActivities 的值几乎总是一个空数组。因此,您可以进一步将您的方法重新定义为:

    -(void)getAllActivities{
       //...
       //No return here!
    }
    

    最后,由于您的方法根本不是真正“获取”活动,您可以考虑将其命名为:

    -(void)reloadAllActivities
    

    【讨论】:

      猜你喜欢
      • 2016-09-24
      • 2017-09-20
      • 1970-01-01
      • 2012-08-11
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      • 2022-11-22
      相关资源
      最近更新 更多