2012-06-24 32 views
1

有谁知道为什么bmlabel没有更新?日志“分数”什么都没有显示?如果没有GCD,它可以正常工作,但它会阻止用户界面(例如,我想显示100到500之间的数字,例如显示101,102 ... 499,500非常快,而不是直接从“100”到“ 500" )。所以我想用另一个线程来计算它,即使我不确定这是最好的方法。这里是我的代码:为什么我的GCD方法没有响应?

//in .h, i imported : 
#import <Foundation/Foundation.h> 
#import <UIKit/UIKit.h> 


//in .m 
@implementation ScoreLayer 

-(void)updateScore:(int)num{ 
    CCLOG(@"hello"); 
    int newScore = score+num; 
    //dispatch_queue_t queue = dispatch_queue_create("Test", 0); 
    dispatch_queue_t main = dispatch_get_main_queue(); 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul); 

    dispatch_async(queue, ^{ 
     for (int i=score; i< newScore; i++){ 
      score++; 
      CCLOG(@"score:%i", score); 
      NSString *str = [NSString stringWithFormat:@"%d", score]; 

      dispatch_async(main, ^{ 
       [bmlabel setString:str]; 
      }); 

     } 
    }); 
    score = newScore; 
} 

-(id) init 
{ 
    if((self=[super init])) { 
     bmlabel = [CCLabelBMFont labelWithString:@"14763" fntFile:@"TestFont.fnt"]; 
     bmlabel.anchorPoint = ccp(0, 0.5f); 
     bmlabel.position = ccp(0,250.0f); 
     [self addChild:bmlabel z:200]; 
      score = 14763; 
    } 
    return self; 
} 

非常感谢正在异步执行

+0

我不使用cocos2d,但会自动设置标签使其刷新,或者您是否需要发送另一条消息以使屏幕上的版本自行绘制? – gaige

+0

会做'CCLOG(@“score:%i”,score);'打印是否正确? – Johnnywho

+0

谢谢,我感谢你的帮助! @gaige对不起,我不确定要理解你的问题,我希望文本被更新为++,直到我到达newScore编号(setString在“main”队列中)。 – Paul

回答

2

我认为score属性是__block类型,因为你在改变行这里面块:

score++; 

,因为你的块与dispatch_async主循环执行的继续执行,您的封锁之前,最有可能遇到score = newScore;甚至开始。当你的块即将运行时,score已经等于newScore,你的循环将永远不会工作,因为它的条件表达式将返回false。在:

for (int i=score; i< newScore; i++) 

i将等于newScore因为newScore < newScore是假的,你的循环将永远不会运行。

我建议删除updateScore:方法中的最后一行。

score = newScore; 
+0

谢谢你的答案Johnnywho!它现在工作正常!那么,我怎么能在最后更新“分数”呢?我尝试将score = newScore放在队列中的for循环之后,但它不起作用:它得到正确的分数,例如15 869,然后下降到15 327 ...? – Paul

+0

也许尝试在第二个块中使用'dispatch_sync'而不是'dispatch_async'。只是为了确保循环顺序执行。 – Johnnywho

+0

如果这没有帮助。也许你的'updateScore:'方法被多次调用,这就是为什么分数不会按顺序更新的原因。我会建议在外部方法中创建队列,因为现在您要为每个方法调用创建一个新的队列,这可能是一个原因。尝试将队列声明为'ivar',并在'init'或其他可以创建一次的地方创建队列,然后在updateScore中使用您的共享队列:' – Johnnywho

2

你的块,这意味着该块新的运行循环执行(=设置scorenewScore后)。

相关问题