2012-02-20 48 views
0

我製作了一個名爲「Tile」的類,它是一個正方形,並且傳遞的塊在被觸摸時會被調用。目標c傳遞塊作爲OOP的參數

-(id) initWithRect: (CGRect) r color: (ccColor4B) c block: (void (^) (void)) blk { 
    if ((self = [super init])) { 
     rect = r; 
     color = c; 
     block = blk; 
     tile = [CCLayerColor layerWithColor:color width:rect.size.width height:rect.size.height]; 
     tile.position = ccp(rect.origin.x, rect.origin.y); 
     [self addChild: tile]; 
     self.isTouchEnabled = YES; 
    } 
    return self; 
} 

//矩形是正方形,我用CCLayerColor來表示正方形。

-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { 
    CGPoint touchLocation = [Helper locationFromTouch: touch]; 
    if (CGRectContainsPoint(rect, touchLocation)) { 
     block(); 
     [tile setColor:ccGRAY]; 
     return YES; 

    } 
    else { 
     return NO; 
    } 
} 

//觸摸時,只需調用該塊。

然後我做一些瓷磚如下:

Tile* aTile = [Tile tileWithMidPos:ccp(512, 500) width:300 height:200 color:ccc4(250, 250, 250, 250) block:^{ 
      [Helper playEffectButtonClicked]; 
     }]; 

,但所有的瓷磚實際執行由最後的區塊通過區塊。 這裏有什麼問題? (每個瓦片是一個對象,所以他們應該調用自己的塊)

回答

2

塊被分配在堆棧上。

在這種情況下,瓷磚類應使BLK參數的副本:

-(id) initWithRect: (CGRect) r color: (ccColor4B) c block: (void (^) (void)) blk { 
    if ((self = [super init])) { 
     rect = r; 
     color = c; 
     block = [blk copy]; 
     tile = [CCLayerColor layerWithColor:color width:rect.size.width height:rect.size.height]; 
     tile.position = ccp(rect.origin.x, rect.origin.y); 
     [self addChild: tile]; 
     self.isTouchEnabled = YES; 
    } 
    return self; 
} 

- (void)dealloc { 
    [block release]; 
    [super dealloc]; 
} 

如果使用ARC,你不需要擔心內存管理(複製和釋放),如果他們傳遞給具有塊參數的方法。如果你通過堆棧分配的內存塊的對象與id參數,你也必須複製:

[myArray addObject:[^{ // some block } copy]]; 

邁克水曲柳具有an article很值得一讀有關塊和ARC。