【问题标题】:Objective-C. Using blocks to reduce amount of code?目标-C。使用块来减少代码量?
【发布时间】:2012-03-23 08:56:47
【问题描述】:

例如,我需要实现一个物体移动。就是左、右、上、下方法。

已编辑

以下代码不正确,但我希望它能更好地解释我需要的东西:

@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

【问题讨论】:

  • Tark 几乎解决了我的问题。仍然存在的问题是,当我需要区分的这些方法在一个类中时。例如draw1、draw2、draw3...
  • 使用 lambdas 是一种非常好的方法。但是在编辑您的问题后,它从令人困惑变为不存在;)您想知道什么?
  • 我自己找到了解决办法

标签: objective-c delegates protocols block codeblocks


【解决方案1】:

您的问题有点不清楚,但从 Java 代码 sn-p 听起来您想在多个类上调用一个方法。这在 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,但不是答案。如果我有任何带有方法 draw1、draw2、draw3 的 A 类并且我必须全部识别它们怎么办?是否可以仅使用 if 或 case 块?
  • 我不确定我是否理解。为什么不能将所有方法都添加到协议中?你能把问题编辑得更清楚一点吗?
  • 我又编辑了。我希望现在会更清楚。我不能将这些方法添加到一个协议中,因为我应该在它们之间区分这些方法(不同类的方法不同)。不过还是谢谢你的临时解决方案
  • 很抱歉,目前还不清楚您无法实现什么。您的解决方案有什么问题?
【解决方案2】:

解决方案

以我为例:

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

右、上、下方法与左方法类似。所以不要告诉我这是不正确的问题或解决方案是不可能的

【讨论】:

    【解决方案3】:

    不确定我是否明白你的意思,但你在目标 C 中使用 setter 和 getter 来修改你的变量。因此,在实例对象的实现中,您可以编写直接影响您的 ivars 的代码。

    我想您已将位置定义为属性,这就是您说无法分配它的原因。

    @property (nonatomic) CGPoint position;
    

    但是,如果您在实现中设置:

    @synthesize position = _position;
    

    那你可以直接这样修改

    _position.x++;
    

    这意味着你可以编写一个类似的方法

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

    如果这不是您的意思,请在您的问题中更加明确。

    【讨论】:

    • 位置是在 cocos2d 库中预定义的。我仅以此为例。可能会有更难的代码。例如准备网络连接、序列化对象并通过该网络发送以及反序列化应答对象
    【解决方案4】:

    您可以编写一个通过检查参数来处理差异的组合方法:

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

    并从您的特定方法中调用它

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

    【讨论】:

    • 至少如果你建议我这个例子,你应该定义所有可能的方向来使用它们,而不需要你可以混淆的数字。第二,您建议手动检查函数发送器,这是不好的。
    • 这是对您最初问题的回答:已知数量的方法(上、下、左、右)在一行中不同,如何最小化冗余代码?保持简单的任务简单易读。
    • 现在看看我的解决方案并与你的比较
    • 我喜欢你的解决方案,就像我喜欢我的一样。也许还有更多的工作模式,试着找到它们:)
    猜你喜欢
    • 2023-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多