Получение «освобождения, в то время как наблюдатели значения ключа все еще были зарегистрированы с этим».ошибки после преобразования в ARC - PullRequest
4 голосов
/ 18 октября 2011

Я использую этот класс:

https://github.com/alexleutgoeb/ALPickerView

Поскольку я преобразовал в ARC, я получаю эту ошибку после того, как пару раз щелкнул по представлению выбора:

2011-10-18 14:10:19.424 MappingApp[3398:10d03] An instance 0x73c7cd0 of class CustomTapGestureRecognizer was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info: <NSKeyValueObservationInfo 0x5d93430> (<NSKeyValueObservance 0x5d933f0: Observer: 0x5d66eb0, Key path: state, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x746b180>)

Ошибка указывает на класс CustomTapGestureRecoginizer и последнюю строку этого метода:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    // Simple hack, set recognizer state to possible as tap begins
    self.state = UIGestureRecognizerStatePossible;
}

В checkview у меня есть этот метод:

- (void)didMoveToSuperview {
    gestureRec = [[CustomTapGestureRecognizer alloc] initWithTarget:nil action:nil];
    gestureRec.numberOfTapsRequired = 1;
    [gestureRec addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:nil];
    [[self superview] addGestureRecognizer:gestureRec];
}

И removeObserver, который, как я знаю, может вызвать эту проблему, находится в dealloc checkview. Должен ли я переместить это куда-нибудь еще? У кого-нибудь есть другие идеи, что может быть причиной этой проблемы? Этого никогда не было до ARC.

1 Ответ

5 голосов
/ 18 октября 2011

Я бы предположил, что метод didMoveToSuperview в классе CheckView вызывается более одного раза, что приводит к переназначению переменной экземпляра gestureRec, и предыдущий экземпляр CustomTapGestureRecognizer считается не имеющим ссылок в ARC, а затембыть освобожденным (вызывая предупреждение о том, что кто-то все еще наблюдает за экземпляром).

Попробуйте добавить NSLog(@"didMoveToSuperview: self=%@ gestureRec=%@", self, gestureRec); к началу didMoveToSuperview, чтобы увидеть, так ли это.

Еслипоэтому быстрое исправление, вероятно, примерно так, но я сам не пробовал и не знаю много о коде.

- (void)didMoveToSuperview {
  if (gestureRec != nil) {
    [gestureRec removeObserver:self forKeyPath:@"state"];
  }
  gestureRec = [[CustomTapGestureRecognizer alloc] initWithTarget:nil action:nil];
  gestureRec.numberOfTapsRequired = 1;
  [gestureRec addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:nil];
  [[self superview] addGestureRecognizer:gestureRec];   
}
...