[英]Objective C - Constants with behaviour
我是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.
这种方法导致指示的错误。 在目标C中是否有更好的方法可以做到这一点
简洁版本
存储方向的几何表示(使用矢量或简单角度),并动态计算方向名称。 要获得左右方向,请复制矢量并将其旋转±½π或±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
编辑:关于使用基本方向作为单独对象的一些说明。
在实践中,您的Direction类可能看起来像这样:
@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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.