2013-08-02 1 views
7

블록 내부에 존재하는 : 나는 self.scoreDictionary를 인쇄 할 때, 코드 내부의 주석 섹션 당findObjectsInBackgroundWithBlock는 : 구문 분석에서 데이터를 얻을 수 있지만, 데이터는 내가 구문 분석에서 데이터를 검색 사용해 다음 테스트 클래스를 만들어

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

코드 안에는 괜찮습니다. 그리고 점진적으로 채워지는대로 전체 사전을 봅니다. 그러나 블록이 끝난 후 사전을 다시 인쇄하면 이제는 비어 있습니다. 나는 쿼리 API 문서를 두 번 확인했지만 여전히 잘못하고있는 것이 확실하지 않습니다.

답변

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를 변경 포함, 당신은 할 것 주 스레드에서 실행됩니다.

+0

감사합니다. 특히 스레드를 보여주는 매우 유용한 그림입니다! – daspianist

관련 문제