5

I am working on a turn based iOS game and trying to populate my list of games the player is participating in.

for (unsigned i = 0; i < [matches count]; i++)
{
    // Only load data for games in progress.
    // NOTE: Might want to handle finished games later.
    if ([matches[i] status] != GKTurnBasedMatchStatusEnded)
    {

        // Send off another block to retrieve the match's data.
        [(GKTurnBasedMatch*)matches[i] loadMatchDataWithCompletionHandler: ^(NSData *matchData, NSError *error)
         {
             // Prepare the game.
             Game* game;
             if (matchData.length == 0)
             {
                 // If the match data is empty, this is a new game. Init from scratch.
                 game = [[Game alloc] init];
             }
             else
             {
                 // Otherwise, unpack the data and init from it.
                 game = [NSKeyedUnarchiver unarchiveObjectWithData:matchData];
             }
             game.match = matches[i];

             // Load the displayNames for the players.
             bool lastIndex = i == ([matches count] - 1);
             [self loadPlayerIdentifiersForGame:game intoArray:blockGames lastIndex:lastIndex];
         }];
    }
}

Unfortunately, I am having an issue where I can't tag each block with its index. That is, i is always 0 by the time the block executes. Is there a way that I can make sure the block knows what i WAS at the time it was launched?

2
  • 2
    Each block should capture exactly the value of i at the time the block is created. I cannot see why i should be always zero when the block is executed.
    – Martin R
    Commented Jun 13, 2013 at 3:51
  • did you try instead of i, capture the __block int j=i; and then instead of i use the j ?
    – taffarel
    Commented Jun 13, 2013 at 4:40

3 Answers 3

0

I sidestepped the issue where my UITableView wouldn't reload if the last game was over by doing this instead:

GKTurnBasedMatch* match;
for (int j = ([matches count] - 1); j >= 0; j --)
{
    match = matches[j];
    if (match.status != GKTurnBasedMatchStatusEnded)
        break;
}
bool lastIndex = (matches[i] == match);
[self loadPlayerIdentifiersForGame:game intoArray:blockGames lastIndex:lastIndex];
0
-(void)someMethod {
    ...
    for (unsigned i = 0; i < [matches count]; i++)
    {
        // Only load data for games in progress.
        // NOTE: Might want to handle finished games later.
        if ([matches[i] status] != GKTurnBasedMatchStatusEnded)
            [self loadMatch:i of:matches];
    }
}

-(void) loadMatch:(int)i of:(NSArray *)matches {
    // Send off another block to retrieve the match's data.
    [(GKTurnBasedMatch*)matches[i] loadMatchDataWithCompletionHandler: ^(NSData *matchData, NSError *error)
     {
         // Prepare the game.
         Game* game;
         if (matchData.length == 0)
         {
             // If the match data is empty, this is a new game. Init from scratch.
             game = [[Game alloc] init];
         }
         else
         {
             // Otherwise, unpack the data and init from it.
             game = [NSKeyedUnarchiver unarchiveObjectWithData:matchData];
         }
         game.match = matches[i];

         // Load the displayNames for the players.
         bool lastIndex = i == ([matches count] - 1);
         [self loadPlayerIdentifiersForGame:game intoArray:blockGames lastIndex:lastIndex];
     }];
}
0

the simplest way is to pass a third parameter containing the tag..

And I suggest to use typedef.. to better write code (and let autocompletion work for you..)

typedef void (^CompletionBlock)(NSInteger tag, NSData * data, NSError *err);

and use CompletionBlock when defining loadMatchDataWithCompletionHandler.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.