2012-06-24 31 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後)。

相關問題