Как я могу отладить ошибку "нераспознанный селектор отправлен в экземпляр"

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

[UITableViewCellContentView image]: unrecognized selector sent to instance 0x7fb4fad7fd20'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010ccbb3f5 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010e7e9bb7 objc_exception_throw + 45
    2   CoreFoundation                      0x000000010ccc250d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x000000010cc1a7fc ___forwarding___ + 988
    4   CoreFoundation                      0x000000010cc1a398 _CF_forwarding_prep_0 + 120
    5   UIKit                               0x000000010d7d8881 -[UITableViewCell _marginWidth] + 151
    6   UIKit                               0x000000010d7ca23d -[UITableViewCell _separatorFrame] + 70
    7   UIKit                               0x000000010d7ca6fa -[UITableViewCell _updateSeparatorContent] + 360
    8   UIKit                               0x000000010d7d4e85 -[UITableViewCell _setSectionLocation:animated:forceBackgroundSetup:] + 1174
    9   UIKit                               0x000000010d634ea8 __53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 1822
    10  UIKit                               0x000000010d5b5eae +[UIView(Animation) performWithoutAnimation:] + 65
    11  UIKit                               0x000000010d63477b -[UITableView _configureCellForDisplay:forIndexPath:] + 312
    12  UIKit                               0x000000010d63bcec -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 533
    13  UIKit                               0x000000010d61b7f1 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2846
    14  UIKit                               0x000000010d63165c -[UITableView layoutSubviews] + 213
    15  UIKit                               0x000000010d5be199 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
    16  QuartzCore                          0x00000001114b6f98 -[CALayer layoutSublayers] + 150
    17  QuartzCore                          0x00000001114abbbe _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
    18  QuartzCore                          0x00000001114aba2e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
    19  QuartzCore                          0x0000000111419ade _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
    20  QuartzCore                          0x000000011141abea _ZN2CA11Transaction6commitEv + 390
    21  QuartzCore                          0x000000011141b255 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89
    22  CoreFoundation                      0x000000010cbf0347 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    23  CoreFoundation                      0x000000010cbf02a0 __CFRunLoopDoObservers + 368
    24  CoreFoundation                      0x000000010cbe60d3 __CFRunLoopRun + 1123
    25  CoreFoundation                      0x000000010cbe5a06 CFRunLoopRunSpecific + 470
    26  GraphicsServices                    0x0000000110daa9f0 GSEventRunModal + 161
    27  UIKit                               0x000000010d545550 UIApplicationMain + 1282
    28  TestWork                          0x000000010caa432e top_level_code + 78
    29  TestWork                          0x000000010caa436a main + 42
    30  libdyld.dylib                       0x000000010efc3145 start + 1
    31  ???                                 0x0000000000000001 0x0 + 1
)

Подскажите, пожалуйста, как устранить эту ошибку?

Спасибо.

Я добавляю точку останова исключения в моем проекте.

Это линия, где она ломается.

  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as ItemTableViewCell  <---------------

Но я не использую "изображение" в моем коде.

9 ответов

Попробуйте установить символическую точку останова на -[NSObject(NSObject) doesNotRecognizeSelector:], Просто нажмите [+] в левом нижнем углу Навигатора точек останова, чтобы добавить точку останова. Затем нажмите "Добавить символическую точку останова". Воспроизведение сбоя теперь должно дать вам лучшее представление о том, где в вашем коде возникает проблема.

Вы можете легко отслеживать такие сбои, используя Exception Breakpoints,

Открой Breakpoint Navigator и добавить

После того, как вы добавите точку останова исключения, откроется опция выбора Exception,

Выбрать Objective-C,

Запустите код и завершите работу приложения, точка останова остановит вас до точки сбоя кода.

Критическим первым шагом является анализ сообщения об ошибке:

[UITableViewCellContentView image]: unrecognized selector sent to instance

Это говорит о том, что "сообщение" image был "отправлен" объекту класса UITableViewCellContentView. (Другими словами, была сделана попытка вызвать метод image на объекте класса UITableViewCellContentView.)

Первое, что нужно спросить: "Имеет ли это какой-либо смысл?" Возможно, что указанный класс имеет Image метод, но не image метод, и поэтому неправильное имя метода было использовано при вызове. Или может быть, что названный метод someMethod:someParm:, но класс реализует someMethod:someParm:anotherParm:Это означает, что параметр был опущен при вызове.

Чаще всего, тем не менее, у названного класса нет никакого метода, даже смутно напоминающего именованный метод, что означает, что каким-то образом указатель на неправильный объект был использован при неудачном вызове.

Например, можно сделать:

NSArray* myArray = [myDictionary objectForKey:@"values"];
NSString* myString = [myArray objectAtIndex:5];

И получите сообщение об ошибке:

[__NSDictionaryI objectAtIndex:] unrecognized selector sent to instance

потому что объект извлечен из myDictionary фактически был NSDictionary, а не NSArray, который ожидался.

К сожалению, наиболее запутанным является тот случай, когда такого рода ошибки происходят в глубине системного кода пользовательского интерфейса, а не в вашем собственном коде. Это может произойти, когда вы каким-то образом передали неправильный объект в системный интерфейс или, возможно, настроили неправильный класс в Интерфейсном Разработчике или где-либо еще.

Другая возможная причина заключается в том, что исходный объект был уничтожен, а затем другой объект был размещен по тому же адресу памяти. Затем ваш код отправляет сообщение, думая, что у него все еще есть указатель на старый объект, и Objective-C выдает исключение, потому что новый объект не понимает это сообщение.

Чтобы диагностировать эту проблему, запустите Профилировщик с обнаружением "Зомби".

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

let canWork = yourObject.respondsToSelector(Selector("image"))   // true

Только если это правда, что код будет работать.. в противном случае он обязательно потерпит крах

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

let noteListTableViewCellobject = "NoteListTableViewCell";` `// Note listTablecell create custom cell`

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

    var cell:NoteListTableViewCell? = tableView.dequeueReusableCellWithIdentifier(noteListTableViewCellobject) as? NoteListTableViewCell

    if (cell == nil) {
        let nib:Array = NSBundle.mainBundle().loadNibNamed("NoteListTableViewCell", owner: self, options: nil)
        cell = nib[0] as? NoteListTableViewCell
    }
}

В этих сценариях мне было полезно взглянуть на две вещи

  1. Стек вызовов
  2. Локальные переменные (и их типы) в каждом кадре стека

Когда у меня была эта ошибка, это обычно потому, что я отправил сообщение экземпляру типа A, когда ожидал тип B.

В этом конкретном сценарии вы, возможно, не удовлетворяете требованию родительского класса (учитывая, что ваш экземпляр ItemTableViewCell наиболее вероятно наследует).

Можете ли вы показать нам код для вашего класса ItemTableViewCell?

Вы должны пройти indexPath объявить объект ячейки tableview.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)

    return cell
}

У меня была такая же проблема, и это сработало для меня:

Переопределите isEqual в вашей SKScene:

- (BOOL)isEqual:(id)other {

    if (![other isMemberOfClass:[SKScene class]]) {
        return false;
    }
    return [super isEqual:other];
}
Другие вопросы по тегам