Objective-C.Используя блоки, чтобы уменьшить количество кода? - PullRequest
0 голосов
/ 23 марта 2012

Например, мне нужно реализовать перемещение объекта.Методы влево, вправо, вверх и вниз.

Отредактировано

Следующий код неверен, но я надеюсь, что он объяснит, что мне нужно лучше:

@interface A : NSObject
...
@end

@implementation A
-(void)up
{
  [self moveTo:^{/*block1*/}];
}

-(void)down
{
    [self moveTo:^{/*block2*/}];
}

-(void)left
{
  [self moveTo:^{/*block3*/}];
}

-(void)right
{
  [self moveTo:^{/*block4*/}];
}

-(void)moveTo:(CodeBlock *)b {
  //actions before
 ...
  b
  //actions after
 ...
}
@end

Ответы [ 4 ]

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

Ваш вопрос немного неясен, но из фрагмента кода Java кажется, что вы хотите вызвать метод для нескольких классов. Это очень просто в Obj-C, так как это динамический язык. Вы можете просто привести объект к типу id и вызвать любой метод для него, если в этом объекте реализован этот метод.

Чтобы сделать это более формально, вы должны определить протокол:

@protocol Drawable <NSObject>
- (void)draw;
@end

Тогда любой класс, которому необходимо реализовать этот протокол, может объявить его в заголовке:

@interface A : NSObject <Drawable>

Затем просто реализуйте метод в классе A. Подпись метода в классе C станет:

- (void)show:(id<Drawable>)r
{
    [r draw];
}

Другим простым решением было бы использование иерархии классов, когда суперкласс реализует метод -(void)draw, и каждый подкласс, который нуждался в другой реализации, мог его переопределить.

1 голос
/ 25 марта 2012

Решение

Для моего примера:

-(void)left
{
    [self moveTo:^(CGPoint p) {
        p.x--;
        return p;
    }];
}

-(void)moveTo:(CGPoint(^)(CGPoint))block
{
    CGPoint p = sprite.position;
    p = block(p);
    sprite.position = p;
}

Методы вправо, вверх и вниз аналогичны методу слева.Так что не говорите мне, что это неправильный вопрос или что решение невозможно

0 голосов
/ 23 марта 2012

Вы можете написать один комбинированный метод, который обрабатывает разницу, проверив аргумент:

(void)methodNameCombined:(NSInteger)direction
{
    ...
    switch(direction) {
        case 1:
            x++;
            break;
        case 2:
            y++;
            break;
    }
    ...
}

и вызывайте его из ваших конкретных методов

(void)methodNameUp
{
    [self methodNameCombined:1]
}

(void)methodNameRight
{
    [self methodNameCombined:2]
}
...
0 голосов
/ 23 марта 2012

Не уверен, что я понял, что вы имеете в виду, но вы в цели C используете сеттеры и геттеры для изменения ваших переменных.Таким образом, в вашей реализации объекта экземпляра вы можете написать код, который напрямую влияет на ваши ivars.

Я полагаю, у вас есть позиция, определенная как свойство, и поэтому вы говорите, что не можете назначить ее.

@property (nonatomic) CGPoint position;

Однако в реализации, если вы установите:

@synthesize position = _position;

, вы можете изменить его прямо так:

_position.x++;

, что означает, что вы можете написатьметод, который похож на

-(void) moveLeftBy:(int) x
{
    _position.x += x;
} 

Если вы не это имеете в виду, пожалуйста, будьте более точны в своем вопросе.

...