如何在 iPhone / XCode 中定义静态字符串表?

发布于 2024-11-19 14:38:44 字数 1981 浏览 0 评论 0原文

当我开发自定义手势时,我需要一个用于调试/跟踪消息的状态名称表。这个声明及其用法有什么问题?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

¢蛋碎的人ぎ生 2024-11-26 14:38:44

当您将对象的引用存储在静态变量中时,您需要确保它不会被释放。因此,您可以向其发送 retain 消息,或者使用 alloc 而不是便捷的创建方法来创建。例如:

    dictStateNames = [[NSDictionary dictionaryWithObjectsAndKeys:
                      // List of objects and keys...
                      nil] retain];

或者这个...

    dictStateNames = [NSDictionary alloc] initWithObjectsAndKeys:
                      // List of objects and keys...
                      nil];

另外,您可以将 stateNames getter 和初始化代码合并到一个方法中,因此您通常会看到 Objective-C 开发人员编写如下方法

+ (NSDictionary *)stateNames
{
    static NSDictionary *stateNames;

    if (stateNames == nil) {
        stateNames = [NSDictionary alloc] initWithObjectsAndKeys:
                      // List of objects and keys...
                      nil];
    }

    return stateNames;
}

: ,没有必要在实例方法中调用它(无论如何这都是错误的,因为每次初始化实例时都会创建一个新字典,除非您以不同的方式处理它,否则前一个字典将会泄漏)。

在另一个(不相关的)注释中,请考虑重写您的 init 方法,如下所示:

- (id)init
{
    return [self initWithTarget:nil action:NULL];
}

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 with alloc instead of a convenience creation method. For example:

    dictStateNames = [[NSDictionary dictionaryWithObjectsAndKeys:
                      // List of objects and keys...
                      nil] retain];

or this...

    dictStateNames = [NSDictionary alloc] initWithObjectsAndKeys:
                      // List of objects and keys...
                      nil];

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:

+ (NSDictionary *)stateNames
{
    static NSDictionary *stateNames;

    if (stateNames == nil) {
        stateNames = [NSDictionary alloc] initWithObjectsAndKeys:
                      // List of objects and keys...
                      nil];
    }

    return stateNames;
}

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:

- (id)init
{
    return [self initWithTarget:nil action:NULL];
}
相思故 2024-11-26 14:38:44

[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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文