UITableViewCell copyWithZone нераспознанный селектор, отправленный в экземпляр

#ios #objective-c #uitableview #key-value-observing #copywithzone

#iOS #objective-c #uitableview #наблюдение за значением ключа #copywithzone

Вопрос:

Я пытаюсь обновить значения в моей пользовательской tableviewcell (DHtableViewCell) с помощью KVO. Я продолжаю получать эту ошибку. Я знаю, что есть другие, у которых есть такое же исключение, но их решения не помогают.

 -[DHTableViewCell copyWithZone:]: unrecognized selector sent to instance 0x1093958b0
 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: '-[DHTableViewCell copyWithZone:]: unrecognized selector sent to instance 0x1093958b0'
*** First throw call stack:
(
0   CoreFoundation  0x0000000101a40495 __exceptionPreprocess   165
1   libobjc.A.dylib 0x000000010179f99e objc_exception_throw   43
2   CoreFoundation  0x0000000101ad165d -[NSObject(NSObject) doesNotRecognizeSelector:]   205
3   CoreFoundation  0x0000000101a31d8d ___forwarding___   973
4   CoreFoundation  0x0000000101a31938 _CF_forwarding_prep_0   120
5   UIKit           0x00000001004cbee0 -[UILabel _setText:]   126
6   GoalTasker328   0x0000000100001ae4 -[DHTableViewCell observeValueForKeyPath:ofObject:change:context:]   276
7   Foundation      0x000000010139eea2 NSKeyValueNotifyObserver   375
8   Foundation      0x00000001013a06f0 NSKeyValueDidChange   467
9   Foundation      0x000000010136379c -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:]   118
  

Класс, который реализует TableView:cellForIndexPath, устанавливает свойство с именем description

 //.h
@interface DHTableViewCell: UITableViewCell

@property (strong, nonatomic) NSString *description;

@end


//*.m
@interface DHTableViewCell ()

@property (weak, nonatomic) IBOutlet UILabel *detailsOfTask;

@end

- (void)awakeFromNib
{
    // Initialization code
    self.description = @"";

    [self addObserver:self
           forKeyPath:NSStringFromSelector(@selector(description))
              options:NSKeyValueObservingOptionNew context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:NSStringFromSelector(@selector(description))]) {
        [[self detailsOfTask] setText:(NSString *)object]; //**crashes here!!!!
    } 
}
  

Итак, способ работы кода заключается в том, что в методе tableview:cellForIndexpath я устанавливаю свойство cell.description . Затем наблюдатель видит, что значение изменилось, затем он переходит и обновляет текст, которому соответствует UILabel.

Я в тупике. Почему он пытается вызвать copyWithZone? Как я могу обойти это?

Ответ №1:

Проблема в том, что object параметр в вызове observeValueForKeyPath:ofObject:change:context: является экземпляром вашей ячейки. Затем вы просто приводите экземпляр ячейки к NSString . Метка пытается создать копию строки. Поскольку этот вызов copy выполняется в экземпляре ячейки, а не в каком NSString -либо, вы получаете сбой.

Хотя я не вижу смысла прослушивать изменения в описании ячейки, одним из решений было бы следующее:

 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:NSStringFromSelector(@selector(description))]) {
        [[self detailsOfTask] setText:[object description]];
    } 
}
  

Это установит метку в description ячейку. Опять же, это не имеет смысла, но решает вашу непосредственную проблему.