我创建了一个名为“Tile”的类,它是一个正方形,触摸时会调用传递的块。
-(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;
}
// rect是正方形,我使用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;
}
}
//触摸时,只需调用该块即可。
然后我按照以下方式制作几个Tiles:
Tile* aTile = [Tile tileWithMidPos:ccp(512, 500) width:300 height:200 color:ccc4(250, 250, 250, 250) block:^{
[Helper playEffectButtonClicked];
}];
但是所有的tile实际上都执行了最后一个tile传递的块。 这里有什么问题? (每个tile都是一个对象,所以他们应该调用自己的块)
答案 0 :(得分:2)
块在堆栈上分配。
在这种情况下,Tile类应该复制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]];
Mike Ash an article非常值得阅读有关积木和ARC的信息。