【问题标题】:Is it possible to tag blocks?是否可以标记块?
【发布时间】:2013-06-09 08:22:05
【问题描述】:

我正在开发一款基于回合制的 iOS 游戏,并尝试填充玩家参与的游戏列表。

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];
         }];
    }
}

不幸的是,我遇到了一个问题,我无法用索引标记每个块。也就是说,在块执行时,i 始终是0。有没有一种方法可以确保该区块知道 i 在它启动时是什么?

【问题讨论】:

  • 每个块都应该在创建块时准确捕获i 的值。我不明白为什么在执行块时i 应该始终为零。
  • 你试过代替i,捕获__block int j=i;然后代替我使用 j ?

标签: iphone ios objective-c ios6 objective-c-blocks


【解决方案1】:

我回避了我的UITableView 在最后一场比赛结束时不会重新加载的问题,而是这样做:

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];

【讨论】:

    【解决方案2】:
    -(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];
         }];
    }
    

    【讨论】:

      【解决方案3】:

      最简单的方法是传递包含标签的第三个参数..

      我建议使用 typedef.. 来更好地编写代码(并让自动完成为您工作..)

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

      并在定义 loadMatchDataWithCompletionHandler 时使用 CompletionBlock。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-14
        • 2018-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-10
        • 2010-11-05
        • 2012-05-27
        相关资源
        最近更新 更多