Как определить статическую таблицу строк в iPhone / XCode? - PullRequest
3 голосов
/ 11 июля 2011

Мне нужна таблица имен состояний для сообщений отладки / трассировки, когда я разрабатываю свой собственный жест.Что не так с этой декларацией и ее использованием?

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

Ответы [ 2 ]

6 голосов
/ 12 июля 2011

Когда вы сохраняете ссылку на объект в статической переменной, вам нужно убедиться, что он не освобожден.Таким образом, вы можете либо отправить ему сообщение retain, либо создать с помощью alloc вместо удобного метода создания.Например:

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

или это ...

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

Кроме того, вы можете объединить ваш stateNames геттер и код инициализации в один метод, так что вы обычно будетесм. разработчики 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];
}
3 голосов
/ 11 июля 2011

[NSDictionary dictionaryWithObjectsAndKeys] сначала берет объект, за которым следует его ключ (как следует из названия метода), который кажется немного отсталым, но это так.

...