「インスタンスに送信された認識できないセレクター」エラーをデバッグするにはどうすればよいですか


100

テーブルビューのカスタムテーブルセルビューを作成しています。カスタムセル(ストーリーボード内)のイメージビューをコードにすばやく接続した後、次のエラーが発生します。

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

しかし、コードでは「イメージ」を使用していません。


2
あなたはimage]どこかに電話しています...しかし間違ったオブジェクトで。エラーの最初の行はそのことを示しています
ccwasden

1
UITableViewCellContentViewでの[image]の呼び出しを停止します-修正されます。このクラッシュを引き起こしているコードを見せてください。
Grzegorz Krukowski、2014

1
tableViewCellでいくつかの画像を使用したと思いますが、その画像がバンドルに含まれていない可能性があります。
Nand Parikh 2017年

回答:


102

にシンボリックブレークポイントを設定してみてください-[NSObject(NSObject) doesNotRecognizeSelector:][+]ブレークポイントナビゲーターの左下隅をクリックして、ブレークポイントを追加します。次に、「シンボリックブレークポイントの追加」をクリックします。クラッシュを再現すると、コード内のどこで問題が発生するかがわかりやすくなります。

ここに画像の説明を入力してください


17
例外ブレークポイントを追加することもできます
rebello95 2014

1
仲間を救った。
AntiMoron 2016

1
ありがとう、とても便利です
Mohd Sadham 2016年

35

このようなクラッシュは、を使用して簡単に追跡できますException Breakpoints

開くBreakpoint Navigatorと追加

ここに画像の説明を入力してください

例外ブレークポイントを追加すると、オプションを選択してを選択できますException

ここに画像の説明を入力してください

を選択しObjective-Cます。

コードを実行してアプリケーションをクラッシュさせます。ブレークポイントは、コードがクラッシュするところまで停止します。


AppDelegateの1行目で発生します。:(
ダニエルスプリンガー

AppDelegateで記述されたコードの一部を表示できますか?ブレークポイントを一時停止しているところ。また、ログも同様です。
Vatsal K

アプリのデリゲートが宣言されている1行目で一時停止します
Daniel Springer

一部のフレームワークが原因で一時停止する場合がありますが、アプリケーションを実行するために続行ボタンを3〜4回押す必要があるかもしれないことを心配しないでください。
Vatsal K

それはそのような場合のエラーではありません、いくつかの古いフレームワークはこの種の問題を引き起こしています。古いフレームワークを新しいフレームワークに更新してみてください。これで問題は解決します。
Vatsal K

30

重要な最初のステップは、エラーメッセージを分析することです。

[UITableViewCellContentView image]: unrecognized selector sent to instance

これは、「メッセージ」imageがUITableViewCellContentViewクラスのオブジェクトに「送信」されたことを示しています。(つまり、imageUITableViewCellContentViewクラスのオブジェクトでメソッドを呼び出そうとしました。)

最初に尋ねるのは、「これはまったく意味があるのですか?」です。名前付きクラスに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ではなかったためです。

残念なことに、最も混乱するのは、この種のエラーが自分のコードではなくUIシステムコードで深く発生する場合です。これは、何らかの理由で間違ったオブジェクトをシステムインターフェイスに渡した場合、またはインターフェイスビルダーなどで間違ったクラスを構成した場合に発生する可能性があります。


6

別の考えられる理由は、元のオブジェクトが破棄され、別のオブジェクトが同じメモリアドレスに割り当てられたことです。次に、コードは古いオブジェクトへのポインターをまだ持っていると考えてメッセージを送信し、新しいオブジェクトはそのメッセージを理解できないため、Objective-Cは例外をスローします。

この問題を診断するには、「ゾンビ」を検出してプロファイラーを実行します。


2

Swift 5.0

イントロスペクションを使用して、オブジェクトが特定のセレクターに応答するかどうかを確認できます。

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

それが真実である場合にのみ、コードは機能します。そうでない場合、確実にクラッシュします。


1

これらのシナリオでは、2つのことを確認することが役立つと思いました

  1. 呼び出しスタック
  2. 各スタックフレームでのローカル変数(およびその型)

このエラーが発生したのは、タイプBが予期されていたときに、タイプAのインスタンスにメッセージを送信したためです。

この特定のシナリオでは、親クラスの要件を満たしていない可能性があります(ItemTableViewCellのインスタンスが継承する可能性が最も高いと仮定)。

ItemTableViewCellクラスのコードを見せていただけますか?


1

次のコードを使用して変数を宣言できます。

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

0

私も同じ問題を抱えていましたが、これでうまくいきました:

SKSceneのisEqualをオーバーライドします。

- (BOOL)isEqual:(id)other {

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

0

indexPathテーブルビューセルのオブジェクトを宣言するために渡す必要があります。

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

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

    return cell
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.