Задача c передать блок в качестве параметра с ООП - PullRequest
0 голосов
/ 20 февраля 2012

Я создаю класс с именем "Плитка", который является квадратом, и переданный блок будет вызываться при касании.

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

но все плитки фактически выполняют блок, который передается последней плиткойв чем здесь проблема?(каждая плитка является объектом, поэтому они должны вызывать свой собственный блок)

1 Ответ

2 голосов
/ 01 марта 2012

Блоки размещаются в стеке.

В этом случае класс 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]];

У Майка Эша есть статья , которую стоит прочитать относительно блоков и ARC.

...