繁体   English   中英

PFQueryTableView麻烦填充表视图

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM