7

Parse からのデータの取得を試すために、次のテスト クラスを作成しました。

-(void)retrieveDataFromParse
{
    PFQuery *query = [PFQuery queryWithClassName:@"TestObject"];

    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if(!error){
            for (PFObject *object in objects){
                NSString *nameFromObject = [NSString stringWithFormat:@"%@", [object objectForKey:@"Name"]];
                NSString *dateFromObject = [NSString stringWithFormat:@"%@", [object createdAt]];
                NSString *scoreFromObject = [NSString stringWithFormat:@"%@", [object objectForKey:@"Score"]];
                [self addNewScore:scoreFromObject andDate:dateFromObject forUserName:nameFromObject];
                NSLog(@"The dictionary is %@", self.scoreDictionary); //<-- here it works printing out the whole dictionary
            }
        } else {
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }
    }];
    NSLog(@"The dictionary is %@", self.scoreDictionary); //<- but after the block is called, here the dictionary is again empty...
}

コード内のコメント セクションによると、コードself.scoreDictionary内で印刷すると問題なく動作し、辞書全体が徐々に埋められていくのがわかります。ただし、ブロックが終了した後、辞書を再度印刷すると、空になります。クエリ API ドキュメントを再確認しましたが、何が間違っているのかまだわかりません。

4

2 に答える 2

13

ブロックの完了後、最後のNSLog(@"The dictionary is %@", self.scoreDictionary)ステートメントは実際には実行されません。findObjectsInBackgroundWithBlockメソッドが戻った後に実行されます。findObjectsInBackgroundWithBlockおそらく別のスレッドで何かを実行し、最後の NSLog ステートメントの後、ある程度の時間が経過するまでブロックが実際にはまったく実行されない可能性があります。グラフィカルに、おそらく次のようなことが起こっています。

Thread 1 
--------
retriveDataFromParse called
invoke findObjectsInBackgroundWithBlock
findObjectsInBackgroundWithBlock queues up work on another thread
findObjectsInBackgroundWithBlock returns immediately      |
NSLog statement - self.scoreDictionary not yet updated    |
retriveDataFromParse returns                              |
.                                                         V
.                       Thread 2, starting X milliseconds later
.                       --------
.                       findObjectsInBackgroundWithBlock does some work
.                       your block is called
.                       for-loop in your block
.                       Now self.scoreDictionary has some data
.                       NSLog statement inside your block

おそらく、取得した後、scoreDictionary データで何をしたいですか? たとえば、UI を更新したり、他のメソッドを呼び出したりしますか? ブロック内でこれを実行すると、データが正常に取得されたことがわかります。たとえば、リロードしたいテーブル ビューがある場合は、次のようにします。

for (PFObject *object in objects){
    ....
}
dispatch_async(dispatch_get_main_queue(), ^{
    [self updateMyUserInterfaceOrSomething];
});

dispatch_asyncデータの更新後に必要な作業に UI の変更が含まれる場合は、メイン スレッドで実行する必要があることに注意してください。

于 2013-08-02T16:30:24.843 に答える
0

最後のNSLog(@"The dictionary is %@", self.scoreDictionary)ブロックは、完了ブロックが実行される前に実行されます。その時までに、self.scoreDictionary確かに空になります。

また、完了ブロックはメインスレッドで実行されます。以下のリンクから参照できます。

https://parse.com/questions/what-thread-does-findobjectsinbackgroundwithblock-complete-on

于 2015-05-08T07:05:52.907 に答える