我目前正在研究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];
}
虽然函数内部的NSLog工作正常,但我的问题现在有点扩展了,我觉得我在这里遗漏了一些非常简单的东西。
当我到达@“TANK NAME ARRAY:%@”时......显然它返回null,因为它在处理查询的部分之外。如果我试图通过另一个类提供数据,这对我没有多大帮助。
过去几天我做了很多尝试,我无法想象我错过了一些非常复杂的东西。我很抱歉重新打开这个,但此时我无法绕过它。
关于如何处理这个问题的任何想法?我一如既往地感谢你的帮助。
答案 0 :(得分:2)
可能还有其他问题,但确定这一行:
tableData = [NSArray arrayWithObjects:objects, nil];
是个错误。这将创建一个单元素数组,其第一个元素是结果数组。我认为你可以修复和简化为:
tableData = objects;
关于如何继续的问题,我认为你可以在任何表视图控制器中继续这个类。通过引用tableData来回答表数据源方法(即count
:numberOfRowsInSection
和tableData[indexPath.row]
来配置cellForRowAtIndexPath
:等等。
答案 1 :(得分:1)
编辑后的新问题的新答案:
似乎混合是调用异步服务。我在这里给出两种建议。首先,最简单的可能包含表的视图控制器从异步服务获取其数据,第二,包含解析异步服务的小类。首先是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中查看解析数据。我建议你先建立一个像这样的东西(就像这样),然后才开始