我是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指针 类型'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之外,还有更好的方法吗?也许是threadlocking,以便在加载视图时allActivities不会返回nil?欢迎任何想法。
谢谢!
答案 0 :(得分:1)
getAllActivities
是一个类方法,因此您无法从中访问属性和实例方法。最简单的解决方案是使其成为实例方法。在我看来,考虑到你的情况(试图访问tableView
属性),这种改变是正确的。
此问题的另一种解决方案:
getAllActivities
添加一个块参数,该参数将在外部服务调用成功完成时被调用;在这个区块中,您将重新加载表格self
传递给getAllActivities
并使用它来访问tableView
我注意到的另一件事 - return allActivities;
将不包含上次RestKit调用的结果,因为它将在调用完成之前执行。
答案 1 :(得分:1)
您的getAllActivities
方法被定义为类级方法(因为它的前缀是加号)。您可能要做的是定义一个实例级方法(使用减去代替加号)。
-(NSArray *)getAllActivities
我接下来要注意的是,你没有对通话结果做任何事情,结果也不是你所期望的。您的RKObjectManager的getObjectsAtPath是异步的,将立即返回。这意味着allActivities的值几乎总是一个空数组。因此,您可以进一步将方法重新定义为:
-(void)getAllActivities{
//...
//No return here!
}
最后,由于您的方法根本不是“获取”活动,您可以考虑将其命名为:
-(void)reloadAllActivities