повторно использованный UITableViewCell с KVO - PullRequest
0 голосов
/ 31 января 2019

Представление таблицы с повторно используемым UITableViewCell. Каждая ячейка имеет собственную метку.Эта метка, которую я определил, подкласс UILabel.Метка отображает строку.И строка изменяется в зависимости от NSMutableDictionary.В классе меток я использую KVO для addObserver.Когда значение ключа изменится в NSMutableDictionary, метка получит это изменение и изменит отображаемое значение.Проблема в том, когда NSMutableDictionary removeAllObjects.большинство меток на дисплее ячейки с «-.-», это правильно.Но только метка нескольких ячеек отображает предыдущее значение, это не правильно.Кажется, из-за повторного использования ячеек таблицы, эта ошибка возникает.

Tableview Class:

//Add Observer

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
// Add Observer
   NSDictionary* dic = [_paramters objectAtIndex:indexPath.row];
   if (!dic || dic.count <= 0) {
     return;
   }

  NSString* key = [dic.allKeys objectAtIndex:0];
  if (!key || key.length <= 0) {
    return;
  }

   ParameterTableViewCell* paramCell = (ParameterTableViewCell*)cell;
   //Add Observer
   paramCell.valueLabel.paramKey = key;
}

// Remove Observer
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

  ParameterTableViewCell* paramCell = (ParameterTableViewCell*)cell;
  //Remove Observer
  [paramCell.valueLabel removeKeyObserver:paramCell.valueLabel.paramKey];
}

Label Class
- (void)setParamKey:(NSString *)paramKey{
  if (![_paramKey isEqualToString:paramKey]) {
    [[CnogaCurveManager sharedCurveManager] addParameterValueObserver:self forParameterKey:paramKey];
    _paramKey = paramKey;
  }
}

- (void)removeKeyObserver:(NSString*)paramKey{
 [[CnogaCurveManager sharedCurveManager] removeParameterValueObserver:self forParameterKey:paramKey];
}

- (void)dealloc{
 [[CnogaCurveManager sharedCurveManager] removeParameterValueObserver:self forParameterKey:_paramKey];
}


//This is where I change label's value
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                    change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if([_paramKey isEqualToString:keyPath]){
    dispatch_async(dispatch_get_main_queue(), ^(){
        self.text = [[CnogaCurveManager sharedCurveManager] paramterValueForKey:keyPath];
        if (!self.text){
            self.text = @"-.-";
        }
    });
 }
}

CnogaCurveManager Class

- (void)addParameterValueObserver:(NSObject*)observer forParameterKey:(NSString*)parameterKey{
try {
    if(![NSString stringIsEmpty:parameterKey]){
        if ([self.obeseverKeys containsObject:parameterKey]) {
            return;
        }

        [self.parameterMeasurement addObserver:observer forKeyPath:parameterKey options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
        [self.obeseverKeys addObject:parameterKey];
       }
} catch (NSException *exception) {

}

}

- (void)removeParameterValueObserver:(NSObject*)observer forParameterKey:(NSString*)parameterKey{
try {
    if(![NSString stringIsEmpty:parameterKey]){
        if (![self.obeseverKeys containsObject:parameterKey]) {
            return;
        }

        [self.parameterMeasurement removeObserver:observer forKeyPath:parameterKey];
        [self.obeseverKeys removeObject:parameterKey];
    }
} catch (NSException *exception) {

}

}

1 Ответ

0 голосов
/ 31 января 2019

Вы правы, когда говорите, что проблема возникла из повторно используемой ячейки.

Когда вы набираете removeAllObjects на dic, key будет nil, и это заставляет tableView:willDisplayCell: возвратиться до установки paramCell.valueLabel.paramKey снова.Вот почему вы видите несколько значений, отображающих предыдущее значение.

Чтобы исправить это, сбросьте значение valueLabel.paramKey при повторном использовании ячейки с помощью метода prepareForReuse .Введите код ниже в вашем ParameterTableViewCell классе

- (void)prepareForReuse {
    [super prepareForReuse];
    self.valueLabel.paramKey = @"";
}
...