[英]PFQueryTableView trouble populating table view
我目前正在处理PFQueryTableView,并尝试使用从ViewDidLoad提取的数组中的数据填充它。 更新:我已经将该函数移至NSObject并实现了一个单例,以便在多个类中使用,以使操作脱离视图控制器。 下面是更新的代码:
+ (NSArray *)savedTankArray
{
PFUser *userName = [PFUser currentUser];
NSString *userNameString = [userName objectForKey:@"username"];
PFQuery *query = [[PFQuery alloc] initWithClassName:@"SavedTanks"];
[query whereKey:@"userName" equalTo:userNameString];
[query setValue:@"SavedTanks" forKeyPath:@"parseClassName"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
if (!error)
{
// The find succeeded.
NSLog(@"Successfully retrieved %lu Tanks.", objects.count);
// Do something with the found objects
for (PFObject *object in objects)
{
NSString *tankNameString = [[NSString alloc] init];
NSString *tankCapacityString = [[NSString alloc] init];
tankNameString = [object valueForKey:@"tankName"];
tankCapacityString = [object valueForKey:@"tankCapacity"];
NSLog(@"%@", tankNameString);
NSLog(@"%@", tankCapacityString);
_savedTankArray = [objects objectAtIndex:0];
}
}
else
{
// Log details of the failure
NSLog(@"Error: %@ %@", error, [error userInfo]);
}
}];
NSLog(@"TANK NAME ARRAY: %@", _savedTankArray);
return [_savedTankArray savedTankObjects];
}
虽然该函数内部的NSLogs可以正常工作,但我的问题现在有所扩展,感觉好像在这里缺少了一些非常简单的东西。
到我到达@“ TANK NAME ARRAY:%@” ...时,很明显它返回null,因为它在处理查询的部分之外。 如果我试图通过另一个类将数据引入,这对我没有多大帮助。
在过去的几天里,我已经做了很多尝试,但我无法想象我错过了一件非常复杂的事情。 抱歉,我重新打开了它,但目前无法绕开它。
关于如何处理这个问题有什么想法吗? 我一如既往地感谢您的帮助。
可能还有其他麻烦,但是请确保此行:
tableData = [NSArray arrayWithObjects:objects, nil];
是一个错误。 这将创建一个单元素数组,其第一个元素是结果数组。 我认为您可以将其修复和简化为:
tableData = objects;
关于您如何进行的问题,我认为您可以像在任何表视图控制器中一样进行此类学习。 通过引用tableData[indexPath.row]
来回答表数据源方法(即,它是numberOfRowsInSection
:的count
,而tableData[indexPath.row]
用于配置cellForRowAtIndexPath
:的依此类推)。
编辑后的新问题的新答案:
看来混淆是与调用异步服务。 我将在此处提供两种建议。 首先,是最简单的包含表的视图控制器,它从异步服务获取数据;其次,是包装解析后的异步服务的小类。 首先是VC:
// in a vc with a table view .m
@interface MyViewController ()
@property(weak,nonatomic) IBOutlet UITableView *tableView;
@property(strong,nonatomic) NSArray *array; // this class keeps the array
@end
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[ClassThatHandlesMyQuery doQuery:^(NSArray *results) {
self.array = results;
[self.tableView reloadData];
}];
}
看看其他类中的查询类方法如何采用块参数? 这是必需的,因为查询是异步发生的。
// do the normal table view stuff
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.array.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
PFObject *pfObject = self.array[indexPath.row];
cell.textLabel.text = [pfObject valueForKey:@"someStringProperty"];
return cell;
}
那应该是vc中所需的几乎所有东西。 现在,让我们看看您的查询方法。 它犯了三个错误:(a)没有块参数让调用者获得异步结果;(b)对查询完成块中的数组进行了错误处理;(c)在方法末尾,它错误地认为变量_savedTankArray在块中被初始化。 该代码显示在块下方,但实际上在块运行之前运行。\\
让我们解决所有三个问题。 首先声明一个公共方法:
// ClassThatHandlesMyQuery.h
+ (void) doQuery:(void (^)(NSArray *))completion;
看看如何将块作为参数? 现在实施:
// ClassThatHandlesMyQuery.m
+ (void) doQuery:(void (^)(NSArray *))completion {
// your query code. let's assume this is fine
PFUser *userName = [PFUser currentUser];
NSString *userNameString = [userName objectForKey:@"username"];
PFQuery *query = [[PFQuery alloc] initWithClassName:@"SavedTanks"];
[query whereKey:@"userName" equalTo:userNameString];
[query setValue:@"SavedTanks" forKeyPath:@"parseClassName"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// the job is MUCH simpler here than your code supposed.
// log the result for fun
NSLog(@"did we get objects? %@", objects);
// hand it back to the caller
// notice there's no array kept in this class. it's not needed
// and it would be awkward to do it at the class (not instance) level
completion(objects);
} else {
NSLog(@"bad news from parse: %@", error);
completion(nil);
}
}
// this is important
NSLog(@"hi mom!");
// watch your log output. 'hi mom' will appear before either message
// from the block. why is that? because that block runs later
// after the network request completes. but the hi mom NSLog runs
// just before the network request starts. this is why it's wrong to expect
// any variable set in the block to be initialized here
}
信不信由你,就是这样。 您应该能够完全按照此处所述编写小型视图控制器类和小型查询类,并在UITableView中查看解析数据。 我建议您先构建像这样(完全像这样)的东西,然后开始
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.