重用findObjectsInBackgroundWithBlock方法:Array为nil

时间:2014-02-26 21:37:49

标签: ios objective-c-blocks parse-platform

我对Parse和iOS开发都很​​陌生。基本上我试图实现一个方法来检索一个类中的解析对象,其他类将使用entityName调用它来返回对象。因此,另一个类将使用retrieveRecords作为参数调用方法entityName

但是数组总是返回nil,因为在返回数组之前块方法才会执行。之前(当我的提取对象工作时!)我只有一个方法来检索同一个类中我需要数据的对象,所以我只是声明了一个__block数组来返回数据。

我知道这是一个常见的问题,因为我广泛搜索它,但我似乎无法找到将对象数组返回到另一个类的最佳解决方案,并最终得到更多纠结的代码,这些代码无效。

- (void)doQuery:(NSString *)entityName
{
    //Create query for all Post object by the current user
    PFQuery *workoutQuery = [PFQuery queryWithClassName:entityName];
    [workoutQuery whereKey:@"owner" equalTo:[PFUser currentUser]];

    // Run the query
    [workoutQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            //Save results and update the table
            NSLog(@"Adding objects to the array");
            NSLog(@"Size %lu" , (unsigned long)objects.count);

            //fill the array once the block is BEING EXECUTED
            [self successfulRetrievedArray:objects];
        }
    }];
}

-(NSArray *)successfulRetrievedArray:(NSArray *)objects
{
    self.objectsArray =[[NSMutableArray alloc]initWithArray:objects];
    return self.objectsArray;
}

-(NSArray *)retrieveRecords:(NSString *)entityName
{
    //DO QUERY
    [self doQuery:entityName];

    //RETRIEVE RECORDS
    return self.objectsArray;
}

2 个答案:

答案 0 :(得分:2)

- (void)doQuery:(NSString *)entityName withCompletionBlock:(void (^)(NSArray *objects, NSError *error))completionBlock {
    //Create query for all Post object by the current user
    PFQuery *workoutQuery = [PFQuery queryWithClassName:entityName];
    [workoutQuery whereKey:@"owner" equalTo:[PFUser currentUser]];

    // Run the query
    [workoutQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            //Save results and update the table
            NSLog(@"Adding objects to the array");
            NSLog(@"Size %lu" , (unsigned long)objects.count);

            //fill the array once the block is BEING EXECUTED
            [self successfulRetrievedArray:objects];

            if (completionBlock) {
                completionBlock(objects, nil);
            }
        } else {
            if (completionBlock) {
                completionBlock(nil, error);
            }
        }
    }];  
}

将代码替换为上面的代码。只需将带数组的登录信息放入完成块

即可

答案 1 :(得分:1)

最好的方法是向doQuery:添加一个参数,以便调用者可以提供完成块。该块将接收到的数组作为参数,并在接收到数组时调用。

通过这样做,你可以接受这样一个事实:数据收集是异步的,并且适合方法中的数据收集。

将结果存储在self.objectsArray中并不是很好,因为没有通知呼叫者数据已准备好,并且一次只能进行一次呼叫(因为只有一个地方可以存储结果)。