解析查询后在哪里重新加载 UITableView 数据

Posted

技术标签:

【中文标题】解析查询后在哪里重新加载 UITableView 数据【英文标题】:Where to Reload UITableView Data after parse query 【发布时间】:2016-02-09 02:40:25 【问题描述】:

我无法让我的 UITableView 正确重新加载。我的应用程序有时会工作,有时会崩溃,因为当 tableView 尝试更新时,其中一个数据元素未正确存储在数组中。有人可以指出我重新加载 tableView 的正确位置吗?

- (void)viewDidLoad 
 [super viewDidLoad];
[self queryForNewBooks];

-(void)queryForNewBooks
_bookNameArray = [[NSMutableArray alloc] init];

_authorNameArray  = [[NSMutableArray alloc] init];
_isbnNumberArray = [[NSMutableArray alloc] init];
_bookImageData = [[NSMutableArray alloc] init];

PFQuery *query = [PFQuery queryWithClassName:@"BooksForSale"];
[query orderByDescending:@"createdAt"];
[query findObjectsInBackgroundWithBlock:^( NSArray *objects, NSError *error) 

    if (objects.count >=1) 

        for (PFObject *object in objects) 
            PFFile *imageFile = [object objectForKey:@"image"];
            [imageFile getDataInBackgroundWithBlock:^(NSData *result, NSError *error) 
                if (!error) 
                    NSData *data = result;


                    NSLog(@"HEYYYYYY");
                    if (data == NULL) 

                    
                    else
                    [ _bookImageData addObject:data];

                   //I have tried placing it here [self.tableView reloadData] 



                    // NSLog(@"%@",[_bookImageData objectAtIndex:0]);

                    


                

            

             ];

            NSDictionary *bookNameDictionary = object[@"nameOfBook"];
            NSDictionary *authorNameDictionary = object[@"Author"];
            NSDictionary *bookImageDictionary = object [@"image"];
            NSDictionary *isbnNumberDictionary = object [@"isbnNumber"];
            NSString *objectID = [object objectId];

            if  (bookNameDictionary != NULL)
                NSLog(@"Yo bro here is the book name   %@",bookNameDictionary);


                [_bookNameArray addObject:bookNameDictionary];
                NSLog(@"number: %@", bookNameDictionary);
            

            if (bookNameDictionary == NULL) 
                [_bookNameArray addObject:@""];
                NSLog(@"Blank space");

            

            if (authorNameDictionary != NULL) 
                [_authorNameArray addObject:authorNameDictionary];
                // [_tableData addObject:ft];
                NSLog(@"Author Name : %@",_authorNameArray);
                //  NSLog(@"the table data is %@",_tableData);
            
            if (authorNameDictionary == NULL) 
                [_authorNameArray addObject:@""];
                NSLog(@"Blank space");

            

            if  (isbnNumberDictionary != NULL)
                NSLog(@"Yo bro here is the isbn %@",isbnNumberDictionary);


                [_isbnNumberArray addObject:isbnNumberDictionary];
                NSLog(@"number: %@", isbnNumberDictionary);
                //[self.tableview reloadData];
            

            if (isbnNumberDictionary == NULL) 
                [_isbnNumberArray addObject:@""];
                NSLog(@"Blank space");

            

         /*   if (bookImageDictionary !=NULL)
                [_bookImageData addObject:bookImageDictionary];

            
            if (bookImageDictionary ==NULL)
                [_bookImageData addObject:@""];
                NSLog(@"Blank Space");
            */
            if (objectID != NULL) 
                [_objectIDArray addObject:objectID];
                NSLog(@"object id is : %@",objectID);
            
            if (objectID ==NULL)
                [_objectIDArray addObject:@"blank"];
            

        
    
    // code
];
 //I have tried placing it here [self.tableView reloadData]   

);

 


 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

return [self.bookNameArray count];




(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 
   static NSString *simpleTableIdentifier = @"TableViewCell";

 TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)

    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TableViewCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];

NSLog(@"Here are the book names, %@",_bookNameArray);

cell.bookNameLabel.text = [_bookNameArray objectAtIndex:indexPath.row];
cell.authorNameLabel.text = [_authorNameArray objectAtIndex:indexPath.row];


if ([_bookImageData objectAtIndex:indexPath.row] != NULL ) 
    NSLog(@"it seems to work");
   UIImage *image = [UIImage imageWithData: [_bookImageData objectAtIndex:indexPath.row]];
   cell.bookImageLabel.image = image;

else
    NSLog(@"Error");

    return cell;

更新问题: 这是声明 PFimageView 的正确方法吗? 我可以在 Xib 文件中拖一个 UIImageView 然后 将其类更改为 PFImageView? 将其更改为 PFImageView 后,我应该能够像往常一样将视图链接到插座吗?

#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#import <ParseUI/ParseUI.h>



@interface TableViewCell : UITableViewCell

@property (nonatomic, weak) IBOutlet UILabel *bookNameLabel;
@property (nonatomic, weak) IBOutlet UILabel *authorNameLabel;
@property (nonatomic, weak) IBOutlet PFImageView *bookImageLabel;
@property (nonatomic, weak) IBOutlet UILabel *priceOfBook;


@end


#import <Parse/Parse.h>
#import "TableViewCell.h"
#import <ParseUI/ParseUI.h>

@implementation TableViewCell


@synthesize bookNameLabel =_bookNameLabel;
@synthesize authorNameLabel = _authorNameLabel;
@synthesize bookImageLabel = _bookImageLabel;

- (void)awakeFromNib 
// Initialization code


- (void)setSelected:(BOOL)selected animated:(BOOL)animated 
[super setSelected:selected animated:animated];

// Configure the view for the selected state

@结束

【问题讨论】:

【参考方案1】:

使代码复杂化的部分是需要使用查询返回的对象来获取图像。最简单的解决方案是省略从查询完成处理程序中获取图像。

    相反,循环返回的对象,构建数组(这里也有改进的空间,但现在只是坚持你的问题的崩溃部分)。在_bookImageData 数组中,不要尝试保留图像,而是为每个对象保留PFFile...

    // in the loop of objects, omit getDataInBackground and just do...
    [_bookImageData addObject:object[@"image"]];
    

    上述问题的答案——在哪里重新加载表——在构建表数据源的循环之后。

    for (PFObject *object in objects) 
        // code to build all of the arrays, omitting getDataInBackground
        // ...
    
    [self.tableView reloadData];
    

    在您的表格视图单元格中,将图像视图替换为PFImageView,因为它可以为您获取图像数据(以及其他有用的东西,例如缓存它)。然后您的cellForRowAtIndexPath: 将如下所示...

    // bookImageLabel must be a PFImageView
    // remember, we put the PFFile for each object into the _bookImageData array
    cell.bookImageLabel.file = _bookImageData[indexPath.row];
    [cell.bookImageLabel loadInBackground];
    

【讨论】:

我已尝试实施您的建议,但是我现在收到错误 -[UIImageView setFile:]: unrecognized selector sent to instance 0x7ff738461e90 正如我所提到的,cell.bookImageLabel 必须是 PFImageView,它是 parse 提供的 UIImageView 的子类。如果您在情节提要中创建原型单元格,请选择您添加到单元格的图像视图并将其类更改为 PFImageView。 我用我的 tableCell 类和声明更新了问题我已将图像视图更改为 PFImageView 类,但我得到了同样的错误。 啊通过添加 [PFImageView 类] 使其工作;在我的表格单元实现文件中。非常感谢您的帮助

以上是关于解析查询后在哪里重新加载 UITableView 数据的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 重新加载时闪烁

SwiftyJSON 没有重新加载 UITableView

尝试从查询中将 Parse PFFiles 加载到 UITableView

异步方法完成后在 ViewController 中重新加载数据

页面加载后在上一节重新打开 jQuery 手风琴

重新加载 UITableView 而不重新加载标题部分