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

mob*_*bob 3 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);
}
Run Code Online (Sandbox Code Playgroud)

jle*_*ehr 6

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

    dictStateNames = [[NSDictionary dictionaryWithObjectsAndKeys:
                      // List of objects and keys...
                      nil] retain];
Run Code Online (Sandbox Code Playgroud)

或这个...

    dictStateNames = [NSDictionary alloc] initWithObjectsAndKeys:
                      // List of objects and keys...
                      nil];
Run Code Online (Sandbox Code Playgroud)

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

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

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

    return stateNames;
}
Run Code Online (Sandbox Code Playgroud)

这样,就不需要在实例方法中调用它(无论如何都会出错,因为每次初始化实例时都会创建一个新的字典,除非你以不同的方式处理它,否则前一个会被泄露).

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

- (id)init
{
    return [self initWithTarget:nil action:NULL];
}
Run Code Online (Sandbox Code Playgroud)