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

Я создаю собственное представление ячейки таблицы для моего представления таблицы. После того, как я подключу представление изображения пользовательской ячейки (в раскадровке) к моему коду в 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  <---------------

Но я не использую 'image' в моем коде.

Ответ 1

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

enter image description here

Ответ 2

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

[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, который ожидался.

Наиболее запутанным, к сожалению, является то, что эта ошибка возникает в системном коде пользовательского интерфейса, а не в вашем собственном коде. Это может произойти, когда вы каким-то образом передали неправильный объект системному интерфейсу или, возможно, настроили неправильный класс в Interface Builder или где бы то ни было.

Ответ 3

Вы можете легко отслеживать такие сбои с помощью Exception Breakpoints.

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

введите описание изображения здесь

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

введите описание изображения здесь

Выберите Objective-C.

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

Ответ 4

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

Чтобы диагностировать эту проблему, запустите Profiler с обнаружением "Zombies".

Ответ 5

Следуйте этим набором инструкций для добавления контрольной точки исключения. При запуске приложения он должен остановиться на строке с нарушением кода.

Вы вызываете изображение на UITableViewCellContentView.. конечно, не то, что вы намереваетесь делать

Ответ 6

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

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

- (BOOL)isEqual:(id)other {

    if (![other isMemberOfClass:[SKScene class]]) {
        return false;
    }
    return [super isEqual:other];
}

Ответ 7

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

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

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

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

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

Ответ 8

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

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

Ответ 9

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

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

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

    return cell
}

Ответ 10

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

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

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