Objective C - 具有行为的常量

时间:2010-05-19 09:50:01

标签: objective-c cocoa

我是Objective C的新手。我正在尝试定义具有与之关联的行为的常量。到目前为止,我已经完成了 -

@interface Direction : NSObject {
     NSString *displayName;
}

-(id)initWithDisplayName:(NSString *)aName;

-(id)left; // returns West when North

-(id)right; // return East when North

@end

@implementation Direction

    -(id)initWithDisplayName:(NSString *)aName
    {
        if(self = [super init])
        {
            displayName = aName;
        }   
        return self;
    }

    -(id)left {};
    -(id)right {};

@end

Direction* North = [Direction initWithDisplayName:@"North"]; // error - initializer element is not constant.

此方法会导致指示的错误。在Objective C中有更好的方法吗?

1 个答案:

答案 0 :(得分:4)

简短版

存储方向的几何表示(使用矢量或简单角度)并动态计算方向名称。要获得左右方向,请将矢量复制并旋转±½π或±90°,创建一个新方向并返回该方向。如果你只有90°转弯,你可以使用一个点{0,1},并切换方向,可选择否定它们。 ({0,1}是北; {1,0}是东,{-1,-0}是西,{ - 0,-1}是南,所以如果你使用这种方法,你必须有一些额外的代码,以确定何时否定,何时不去。)

长版

问题是函数之外的变量在编译时被初始化。当然,这意味着您无法调用函数来初始化它们。要做这样的事情,你需要做以下事情(虽然你不应该,见下文):

// Direction.h

extern Direction *north;

// Direction.m

Direction *north = nil;

+ (void)initialize {
  north = [[Direction alloc] initWithDisplayName:@"North"];
}
然而,这是一种几乎完全可怕的事情。您想要做的事情如下:

// Direction.h


@interface Direction (ConstantDirections)

+ (Direction *)north;
// etc...

@end

// Direction.m

+ (Direction *)north {
  static Direction *northDirection = nil;
  if (!northDirection) {
    // assume that ConstantDirection is a subclass of
    // Direction that prevents releases etc.
    northDirection = [[ConstantDirection alloc] initWithDisplayName:@"North"];
  }
  return northDirection.
}

这将阻止该方向的其他用户(主要是)做恶事。

PS: North是一个非常奇怪的词,当你输入很多内容时尤其明显。 :P

编辑:对使用基本路线作为单独对象的一些说明。

在实践中,你的方向类可能看起来像这样:

@interface Direction : NSObject <NSCopying,NSCoding> {
  NSString *displayName;

  NSPoint offset;
  // XOR
  NSInteger northOffset;
  NSInteger eastOffset;
  // XOR
  CGFloat theta;
}

@property (copy) NSString *displayName;
@property (readonly) NSPoint offset;

+ (Direction *)north;
+ (Direction *)east;
+ (Direction *)west;
+ (Direction *)south;

- (id)initWithOffset:(NSPoint)offset;

@end

为了讨论的目的,我们假设第一个。

在这种情况下,您的Direction.m文件将包含以下内容。

@implementation Direction 

+ (Direction *)north {
  static Direction *northDirection = nil;
  if (!northDirection) {
    // assume that ConstantDirection is a subclass of
    // Direction that prevents releases etc.
    northDirection = [[ConstantDirection alloc] initWithOffset:NSMakePoint(0,DIRECTION_LARGE_OFFSET)];
    northDirection.displayName = @"North";
  }
  return northDirection.
}

@end