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

标签 iphone xcode static nsdictionary

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

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);
}

最佳答案

当您将对象的引用存储在静态变量中时,您需要确保它不会被释放。因此,您可以向其发送 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];
}

关于iphone - 如何在 iPhone/XCode 中定义静态字符串表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6652192/

相关文章:

objective-c - 如何通过代码获取 NSObject 的对象 ID?

c++ - 使用带有 Xcode 的 C++ 清除控制台?

java - Xcode 图像链接 ImageView 到下一个 View Controller

Java:父方法访问子类的静态变量?

c++ - 为什么我们应该只在类或函数 (C++) 中使用 'static'?

ios - 通过 iphone 上的应用程序创建日历(在 ios native 日历中)

ios - 在 Swift 中用包含时间的字符串替换当前日期

c++ - C/C++ 静态 Voodoo

php - 防止通过网络浏览器访问 iPhone 应用程序中使用的 PHP 脚本

iphone - 添加平移手势识别器后,我的按钮不会保持突出显示状态?