Como posso depurar o erro de 'seletor não reconhecido enviado para instância'

100

Estou criando uma visualização de célula de tabela personalizada para minha visualização de tabela. Depois de conectar uma visualização de imagem de célula personalizada (no storyboard) ao meu código em swift, recebo o seguinte erro.

[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
)

Você pode me dizer como resolver esse erro?

Obrigado.

Eu adiciono um ponto de interrupção de exceção em meu projeto.

Esta é a linha onde ela se quebra.

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

Mas eu não uso 'imagem' no meu código.

n179911
fonte
2
você está ligando em image]algum lugar .. mas no objeto errado. a primeira linha do erro diz isso a você
ccwasden
1
Pare de chamar [imagem] em UITableViewCellContentView - isso resolveria. Mostre-nos o código que está causando esta falha.
Grzegorz Krukowski de
1
Acho que você usou alguma imagem em tableViewCell, mas essa imagem pode não estar no seu pacote.
Nand Parikh de

Respostas:

102

Tente definir um ponto de interrupção simbólico -[NSObject(NSObject) doesNotRecognizeSelector:]. Basta clicar [+]no canto inferior esquerdo do Breakpoint Navigator para adicionar um breakpoint. Em seguida, clique em 'Adicionar ponto de interrupção simbólico'. Reproduzir sua falha agora deve dar uma ideia melhor onde o problema ocorre em seu código.

insira a descrição da imagem aqui

dbart
fonte
17
Também poderia apenas adicionar um ponto de interrupção de exceção .
rebello95 de
1
Salvou meu dia, mano.
AntiMoron
1
Obrigado, é tão útil
Mohd Sadham
35

Você pode rastrear facilmente essas falhas usando Exception Breakpoints .

Abra o Breakpoint Navigatore adicione o

insira a descrição da imagem aqui

Depois de adicionar o Breakpoint de exceção, a opção será aberta para escolher o Exception.

insira a descrição da imagem aqui

Selecione Objective-C.

Execute o código e bloqueie o aplicativo, o ponto de interrupção o parará no ponto em que o código está causando falha.

Vatsal K
fonte
Acontece na linha AppDelegate 1. E agora? :(
Daniel Springer
Você pode mostrar parte do seu código escrito em AppDelegate? Onde está pausando o ponto de interrupção. E também os logs também.
Vatsal K
ele faz uma pausa na linha 1, onde o delegado do aplicativo é declarado
Daniel Springer,
Existem alguns casos em que ele faz uma pausa, devido a algumas estruturas, mas não se preocupe se você precisar pressionar o botão continuar por 3 a 4 vezes para executar o aplicativo.
Vatsal K
Isso não é um erro nesse caso, alguns frameworks antigos estão causando esse tipo de problema. Tente atualizar seus frameworks antigos para novos / atualizados. Isso deve resolver o problema.
Vatsal K
30

A primeira etapa crítica é analisar a mensagem de erro:

[UITableViewCellContentView image]: unrecognized selector sent to instance

Isso informa que a "mensagem" imagefoi "enviada" para um objeto da classe UITableViewCellContentView. (Em outras palavras, foi feita uma tentativa de chamar o método imageem um objeto da classe UITableViewCellContentView.)

A primeira coisa a perguntar é "Isso faz algum sentido?" Pode ser que a classe nomeada tenha um Imagemétodo, mas não um imagemétodo e, portanto, o nome do método incorreto foi usado na chamada. Ou pode ser que o método nomeado seja someMethod:someParm:, mas a classe o implemente someMethod:someParm:anotherParm:, o que significa que um parâmetro foi omitido na chamada.

Na maioria das vezes, porém, a classe nomeada não possui nenhum método, mesmo vagamente parecido com o método nomeado, o que significa que, de alguma forma, um ponteiro para o objeto errado foi usado na chamada com falha.

Por exemplo, pode-se fazer:

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

E obterá um erro do tipo:

[__NSDictionaryI objectAtIndex:] unrecognized selector sent to instance

porque o objeto recuperado myDictionaryera, na verdade, um NSDictionary, não o NSArray que era esperado.

O mais confuso, infelizmente, é quando esse tipo de erro ocorre profundamente no código do sistema de IU, e não em seu próprio código. Isso pode acontecer quando você de alguma forma passou o objeto errado para uma interface do sistema, ou talvez configurou a classe errada no Interface Builder ou qualquer outro lugar.

Hot Licks
fonte
6

Outra razão possível é que o objeto original foi destruído e, em seguida, outro objeto foi alocado no mesmo endereço de memória. Em seguida, seu código envia a mensagem, pensando que ainda tem um ponteiro para o objeto antigo, e Objective-C lança uma exceção porque o novo objeto não entende essa mensagem.

Para diagnosticar esse problema, execute o Profiler com detecção de 'Zumbis'.

Bryan
fonte
2

Swift 5.0

Você pode usar o Introspection para descobrir se o objeto responde a um seletor específico ou não.

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

Somente se for verdade que o código funcionará .. do contrário, irá travar com certeza

Saranjith
fonte
1

Nestes cenários, achei útil olhar para duas coisas

  1. A pilha de chamadas
  2. As variáveis ​​locais (e seus tipos) em cada estrutura de pilha

Quando recebo esse erro, geralmente é porque enviei uma mensagem para uma instância do Tipo A, quando esperava o Tipo B.

Neste cenário específico, você pode não estar satisfazendo um requisito de uma classe pai (dada sua instância de ItemTableViewCell provavelmente herda).

Você pode nos mostrar o código para sua classe ItemTableViewCell?

abc
fonte
1

Você pode usar o seguinte código para declarar a variável:

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
    }
}
Yogesh Shelke
fonte
0

Eu tive o mesmo problema, e isso funcionou para mim:

Substitua o isEqual em sua SKScene:

- (BOOL)isEqual:(id)other {

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

Você tem que passar indexPatha declarar o objeto da célula tableview.

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

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

    return cell
}
Rohit Parsana
fonte