2013-08-02 24 views
7

tôi đã lớp thử nghiệm sau đây để thử lấy dữ liệu từ Parse:findObjectsInBackgroundWithBlock: nhận dữ liệu từ màu Tây Nguyên, nhưng dữ liệu chỉ tồn tại bên trong các khối

-(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... 
} 

mỗi phần nhận xét bên trong mã, khi tôi in self.scoreDictionary bên trong mã, nó hoạt động tốt, và tôi thấy toàn bộ từ điển của tôi vì nó dần dần được lấp đầy. Tuy nhiên, sau khi khối kết thúc, khi tôi in lại từ điển, nó bây giờ đã trống. Tôi đã kiểm tra lại bằng tài liệu API truy vấn, nhưng tôi vẫn không chắc chắn những gì tôi đang làm không chính xác.

Trả lời

13

Câu lệnh NSLog(@"The dictionary is %@", self.scoreDictionary) cuối cùng không thực thi sau khi khối hoàn tất. Nó thực thi sau khi trả về phương thức findObjectsInBackgroundWithBlock. findObjectsInBackgroundWithBlock có lẽ chạy một cái gì đó trong một chủ đề riêng biệt, và khối của bạn có thể không thực sự thực hiện ở tất cả cho đến khi một khoảng thời gian sau đó tuyên bố NSLog cuối cùng. Đồ họa, một cái gì đó như thế này có lẽ xảy ra:

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 

Bạn có thể muốn suy nghĩ về, những gì bạn muốn làm gì với dữ liệu scoreDictionary của bạn sau khi bạn đã lấy nó? Ví dụ: bạn có muốn cập nhật giao diện người dùng không, hãy gọi một số phương thức khác, v.v.? Bạn sẽ muốn làm điều này bên trong khối của bạn, tại thời điểm đó bạn biết dữ liệu đã được truy xuất thành công. Ví dụ, nếu bạn có một cái nhìn bảng mà bạn muốn tải lại, bạn có thể làm điều này:

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

Lưu ý dispatch_async - nếu công việc bạn cần làm sau khi cập nhật dữ liệu của bạn liên quan đến việc thay đổi giao diện người dùng, bạn sẽ muốn để chạy trên luồng chính.

+0

Cảm ơn, đặc biệt là minh họa rất hữu ích cho thấy các chủ đề! – daspianist

Các vấn đề liên quan