我是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中有更好的方法吗?
答案 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