0

내 parse.com 데이터베이스에 사람 목록을 표시하는 내 페이지에 표시 할 로더 및 회 전자가 필요합니다. 지금은 하나의 컨트롤러 UITableViewController에 집중하고 있습니다.내 UIActivityIndicatorView가 너무 빨리 사라져서 쓸모 없게 만들었습니다.이 문제를 해결하는 가장 좋은 방법이 지연 되었습니까?

여기 내 코드입니다 : 내가 청소 일을 할 parse.com에서 내 데이터를로드하는 코드를 촬영했습니다

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    dispatch_queue_t downloadQueue = dispatch_queue_create("downloader", NULL); 
    UIView *taggedView = [[LoadingView alloc] initWithFrame:[[self view] bounds]]; 
    [taggedView setTag:17]; 
    [[self view] addSubview:taggedView]; 

    dispatch_async(downloadQueue, ^{ 
     //Load my data from parse.com here into an NSMutableArray 
     //which is the used in my datasource methods 
     NSLog(@"downloading"); 


     dispatch_async(dispatch_get_main_queue(), ^{ 
      //Here is where I hide the loader view 
      NSLog(@"downloading done."); 
      UIView *viewToRemove = [[self view] viewWithTag:17]; 
      [viewToRemove removeFromSuperview]; 
     }); 
    }); 

하지만 모두가가는 곳 commeting은 분명히 있습니다.

viewToRemove 행을 주석 처리하지 않으면 로더가 표시되지 않습니다. 그럼 분명히 화면에 그대로 있습니다. 문제는 방금로드되고 너무 빨리 제거됩니다. 또한 어떤 이유로 나는 테이블 행 행을 볼 수 있으며, 나는 그들을보고 싶지 않습니다. 로더 뷰 뷰를 사용하여 데이터가로드 될 때까지 전체 영역을 덮어두기를 원합니다. (웹에서 이걸 발견)

LoaderView 파일 :

#import "LoadingView.h" 

@implementation LoadingView 

#define LABEL_WIDTH 80 
#define LABEL_HEIGHT 20 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     [self setBackgroundColor:[UIColor whiteColor]]; 
     UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake((self.bounds.size.width-LABEL_WIDTH)/2+20, 
                    (self.bounds.size.height-LABEL_HEIGHT)/2, 
                    LABEL_WIDTH, 
                    LABEL_HEIGHT)]; 
     label.text = @"Loading…"; 
     label.center = self.center; 
     UIActivityIndicatorView* spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
     spinner.frame = CGRectMake(label.frame.origin.x - LABEL_HEIGHT - 5, 
            label.frame.origin.y, 
            LABEL_HEIGHT, 
            LABEL_HEIGHT); 
     [spinner startAnimating]; 
     [self addSubview: spinner]; 
     [self addSubview: label]; 
    } 
    return self; 
} 

그래서 내 임무는 회 전자와 단어 "로드"흰색 백그라운드로보기를하는 것입니다. 이 방법을 통해 효율성을 달성 할 수 있습니까? 아니면이를 수행하는 더 좋은 방법이 있습니까? 그렇다면 여기에 도움을 주시면 감사하겠습니다.

종류는

UPDATE에게 나에 대한 데이터를 얻을 수

구문 분석 코드를 간주한다.

// Grab data for datasource and store in people array 
NSLog(@"view will appear"); 
people = [[NSMutableArray alloc] init]; 

PFQuery *query = [PFQuery queryWithClassName:@"People"]; 
[query whereKey:@"active" equalTo:@1]; 
[query orderByDescending:@"createdAt"]; 
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { 

    if (!error) { 
     for (PFObject *object in objects) { 
      // NSLog(@"%@", object); 
      Person *person = [[Person alloc] init]; 
      [person setName:[object objectForKey:@"name"]]; 
      [person setNotes:[object objectForKey:@"notes"]]; 
      [person setAge:[[object objectForKey:@"age"] intValue]]; 
      [person setSince:[object objectForKey:@"since"]]; 
      [person setFrom:[object objectForKey:@"from"]]; 
      [person setReferenceNumber:@"14-334544"]; 

      PFFile *userImageFile = object[@"image"]; 
      [userImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) { 
       if (!error) { 
        UIImage *image = [UIImage imageWithData:imageData]; 
        [person setImage:image]; 
       } 
      }]; 


      [person setActive:[[object objectForKey:@"active"] intValue]]; 
      [person setObjectId:[object objectId]]; 
      [people addObject:person]; 


     } 


     dispatch_async(dispatch_get_main_queue(),^{ 
      [[self tableView] reloadData]; 
     }); 


    } else { 
     // Log details of the failure 
     NSLog(@"Error: %@ %@", error, [error userInfo]); 


    } 


}]; 
+0

다운로드하는 데 사용하는 구문 분석 방법이란 무엇입니까? 그것은'downloadInBackground' 메소드입니까, 아니면 스레드가 차단되어 있습니까? – JuJoDi

+0

옙 it 's findObjectsInBackgroudWithBlock – LondonGuy

답변

0

귀하의 모든 파싱 코드는 비동기식이므로 거의 즉시 완료됩니다. 시각이 실제로 나타나면 (viewDidLoad, viewWillAppear, viewWillLayoutSubviewsviewDidLayoutSubviews 모두 완료 됨) 모든 구문 분석 코드는 즉시 반환되므로 완료됩니다.

원하는 효과를 얻으려면 백그라운드 구문 분석 스레드를 차단해야합니다.

예를 들어, 변경 :

[userImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) { 
    if (!error) { 
     UIImage *image = [UIImage imageWithData:imageData]; 
     [person setImage:image]; 
    } 
}]; 

에 :

NSError *error; 
NSData *imageData = [userImageFile getData:&error]; 
if (!error) { 
    UIImage *image = [UIImage imageWithData:imageData]; 
    [person setImage:image]; 
} 

유사 동기 버전을 사용 [PFQuery -findObjectsInBackgroundWithBlock:]을 변경하는 방법이 필요합니다.

그러나 다음과 같은 대안을 고려하십시오. 로더를 표시하지 말고 백그라운드 블록을 계속 사용하고 들어오는대로 데이터를 표시하십시오. 이것은 로더를 보여주는 것보다 훨씬 좋은 경험입니다.

tl; dr : GCD 비동기 블록과 구문 분석의 백그라운드 블록을 모두 사용하고 있습니다. 둘 중 하나만 사용하십시오.

+0

나는 대체 방법을 사용하는 것을 고려해 보았습니다. 그러나 데이터가로드되기 전에 실제로 두 번째 부분이 실제로 데이터가있는 위치에 "제목"과 "자막"이라는 단어가 표시된다는 것을 알았습니다. 그것이 내가 로더를 원했던 주된 이유입니다. 일어나고있는 모든 것을 숨기기. – LondonGuy

+0

xib/storyboard에서 해당 문자열을 비워두기 만하면됩니다. –

+0

awakeFronNib 메서드에서 프로그래밍 방식으로 변경할 수도 있습니다. –

0

findObjectsInBackgroundWithBlock을 사용하고 있으므로 주 스레드에서 실행될 코드가 즉시 실행되고 개체가 발견되면 블록이 실행됩니다.로더를 제거하는 코드가 해당 블록에 이미 파견 비동기 내에서 실행되어야한다 : 객체를로드하기 전에 세포를 보는 대한 질문에 대해

[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { 
    // do something with the objects 
    dispatch_async(dispatch_get_main_queue(), ^{ 
      [[self tableView] reloadData]; 
      // remove the loader 
      NSLog(@"downloading done."); 
      UIView *viewToRemove = [[self view] viewWithTag:17]; 
      [viewToRemove removeFromSuperview]; 
    }); 
}]; 

, 당신은 당신이 세포를 다시 사용하고 있는지 확인해야하며, tableViewController의 delegate 메소드가 객체의 수에 적절히 응답하고 있으므로 객체를 다운로드하기 전에 반환 할 데이터가 tableview에 저장되지 않도록해야합니다.

관련 문제