Waiting for a block to finish [duplicate]

2019-03-03 23:30发布

This question already has an answer here:

I have a UITableView and I'm attempting to get the number of rows. However, I'm having trouble using blocks. In the code below I'd just like to return count, but as I now understand blocks are asynchronous. I've looked around trying to find a solution but none of them worked. One solution I tried was this: How do I wait for an asynchronously dispatched block to finish? but when I clicked on the button to go to the view with the table, it just froze when the button was clicked. I tried some others, but they also did not work.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  GlobalVars *globals = [GlobalVars sharedInstance];

  __block int count = 0;
  GKLocalPlayer *localPlayer = [[GameCenterHelper sharedInstance] getLocalPlayer];
  [[GameCenterHelper sharedInstance] getMatches:^(NSArray *matches) {
    NSLog(@"Matches: %@", matches);
    for (GKTurnBasedMatch *match in matches) {
      for (GKTurnBasedParticipant *participant in match.participants) {
        if ([participant.playerID isEqualToString:localPlayer.playerID]) {
          if (participant.status == GKTurnBasedParticipantStatusInvited) {
            [globals.matchesReceived addObject:match];
            count++;
            NSLog(@"INVITED");
          }
        }
      }
    }
  }];

  return count;
}

Could someone help me properly get count returned?

1条回答
够拽才男人
2楼-- · 2019-03-04 00:16

You should be using callback blocks. Don't try to make asynchronous code behave synchronously.

Also, there's no need to have your GlobalVars singleton hold onto the array of matches. It could be considered bad design.

typedef void(^CallbackBlock)(id value);

- (void)viewDidLoad {
    [super viewDidLoad];
    //show some sort of loading "spinner" here
    [self loadMatchesWithCallback:(NSArray *matches) {
        //dismiss the loading "spinner" here
        self.matches = matches;
        [self.tableView reloadData];
    }];
}

- (void)loadMatchesWithCallback:(CallbackBlock)callback {
    GlobalVars *globals = [GlobalVars sharedInstance];
    GKLocalPlayer *localPlayer = [[GameCenterHelper sharedInstance] getLocalPlayer];
    [[GameCenterHelper sharedInstance] getMatches:^(NSArray *matches) {
        NSLog(@"Matches: %@", matches);
        NSMutableArray *filteredMatches = [NSMutableArray array];
        for (GKTurnBasedMatch *match in matches) {
            for (GKTurnBasedParticipant *participant in match.participants) {
                if ([participant.playerID isEqualToString:localPlayer.playerID]) {
                    if (participant.status == GKTurnBasedParticipantStatusInvited) {
                        [filteredMatches addObject:match];
                        break; //you don't want to add multiples of the same match do you?
                    }
                }
            }
        }
        if (callback) callback(filteredMatches);
    }];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.matches.count;
}
查看更多
登录 后发表回答