如何在 iPhone / XCode 中定义静态字符串表?
当我开发自定义手势时,我需要一个用于调试/跟踪消息的状态名称表。这个声明及其用法有什么问题?
static NSDictionary *dictStateNames = nil;
@implementation MyCustomGesture
@synthesize state;
+(void)initStateNames {
if (dictStateNames == nil) {
dictStateNames = [NSDictionary dictionaryWithObjectsAndKeys:
@"StateBegan", [NSNumber numberWithInt:UIGestureRecognizerStateBegan],
@"StateCancelled", [NSNumber numberWithInt:UIGestureRecognizerStateCancelled],
@"StateChanged", [NSNumber numberWithInt:UIGestureRecognizerStateChanged],
@"StateEnded", [NSNumber numberWithInt:UIGestureRecognizerStateEnded],
@"StateFailed", [NSNumber numberWithInt:UIGestureRecognizerStateFailed],
@"StatePossible", [NSNumber numberWithInt:UIGestureRecognizerStatePossible],
@"StateRecognized", [NSNumber numberWithInt:UIGestureRecognizerStateRecognized],
nil];
}
}
-(id) init {
self = [super init];
if (self) {
[MyCustomGesture initStateNames];
state = UIGestureRecognizerStatePossible;
}
return self;
}
-(id) initWithTarget:(id)target action:(SEL)action {
self = [super initWithTarget:target action:action];
if (self) {
[MyCustomGesture initStateNames];
state = UIGestureRecognizerStatePossible;
}
return self;
}
+(NSString*) stateName: (UIGestureRecognizerState) state {
NSString *retName = [dictStateNames objectForKey:[NSNumber numberWithInt:state]];
if (retName == nil) {
return [NSString stringWithFormat:@"Unknown state (%@)", state];
} else {
return retName;
}
}
-(NSString*) currentStateName {
return [MyCustomGesture stateName:state];
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"%s (%@): %@", __FUNCTION__, [self currentStateName], event);
}
I want a table of state-names for debug/trace messages as I develop my custom gesture. What is wrong with this declaration and its usage?
static NSDictionary *dictStateNames = nil;
@implementation MyCustomGesture
@synthesize state;
+(void)initStateNames {
if (dictStateNames == nil) {
dictStateNames = [NSDictionary dictionaryWithObjectsAndKeys:
@"StateBegan", [NSNumber numberWithInt:UIGestureRecognizerStateBegan],
@"StateCancelled", [NSNumber numberWithInt:UIGestureRecognizerStateCancelled],
@"StateChanged", [NSNumber numberWithInt:UIGestureRecognizerStateChanged],
@"StateEnded", [NSNumber numberWithInt:UIGestureRecognizerStateEnded],
@"StateFailed", [NSNumber numberWithInt:UIGestureRecognizerStateFailed],
@"StatePossible", [NSNumber numberWithInt:UIGestureRecognizerStatePossible],
@"StateRecognized", [NSNumber numberWithInt:UIGestureRecognizerStateRecognized],
nil];
}
}
-(id) init {
self = [super init];
if (self) {
[MyCustomGesture initStateNames];
state = UIGestureRecognizerStatePossible;
}
return self;
}
-(id) initWithTarget:(id)target action:(SEL)action {
self = [super initWithTarget:target action:action];
if (self) {
[MyCustomGesture initStateNames];
state = UIGestureRecognizerStatePossible;
}
return self;
}
+(NSString*) stateName: (UIGestureRecognizerState) state {
NSString *retName = [dictStateNames objectForKey:[NSNumber numberWithInt:state]];
if (retName == nil) {
return [NSString stringWithFormat:@"Unknown state (%@)", state];
} else {
return retName;
}
}
-(NSString*) currentStateName {
return [MyCustomGesture stateName:state];
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"%s (%@): %@", __FUNCTION__, [self currentStateName], event);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您将对象的引用存储在静态变量中时,您需要确保它不会被释放。因此,您可以向其发送
retain
消息,或者使用alloc
而不是便捷的创建方法来创建。例如:或者这个...
另外,您可以将
stateNames
getter 和初始化代码合并到一个方法中,因此您通常会看到 Objective-C 开发人员编写如下方法: ,没有必要在实例方法中调用它(无论如何这都是错误的,因为每次初始化实例时都会创建一个新字典,除非您以不同的方式处理它,否则前一个字典将会泄漏)。
在另一个(不相关的)注释中,请考虑重写您的
init
方法,如下所示:When you store a reference to an object in a static variable, you need to ensure that it doesn't get deallocated. So you can either send it a
retain
message, or create withalloc
instead of a convenience creation method. For example:or this...
Also, you can coalesce your
stateNames
getter and the initialization code into a single method, so you'll typically see Objective-C developers write a method like this:That way, there's no need to call it in an instance method (which would be wrong anyway, since a new dictionary would be created each time an instance is initialized, and unless you handled it differently, the previous one would be leaked).
On another (unrelated) note, consider rewriting your
init
method as follows:[NSDictionary DictionaryWithObjectsAndKeys]
首先获取一个对象,然后是它的键(如方法名称所示),这看起来有点落后,但确实如此。[NSDictionary dictionaryWithObjectsAndKeys]
takes an object first followed by its key (as the method name suggests), which seems a bit backward but there it is.