Bagaimana cara men-debug kesalahan 'pemilih tidak dikenal dikirim ke instance'

100

Saya membuat tampilan sel tabel kustom untuk tampilan tabel saya. Setelah saya menghubungkan tampilan gambar sel khusus (di storyboard) ke kode saya dengan cepat, saya mendapatkan kesalahan berikut.

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

Bisakah Anda memberi tahu saya cara mengatasi kesalahan ini?

Terima kasih.

Saya menambahkan breakpoint pengecualian dalam proyek saya.

Ini adalah garis yang putus.

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

Tapi saya tidak menggunakan 'gambar' dalam kode saya.

n179911
sumber
2
Anda menelepon ke image]suatu tempat .. tetapi pada objek yang salah. baris pertama kesalahan memberi tahu Anda sebanyak itu
ccwasden
1
Berhenti memanggil [image] di UITableViewCellContentView - itu akan memperbaikinya. Tunjukkan kepada kami kode yang menyebabkan kerusakan ini.
Grzegorz Krukowski
1
Saya pikir Anda telah menggunakan beberapa gambar di tableViewCell tetapi gambar itu mungkin tidak ada dalam bundel Anda.
Nand Parikh

Jawaban:

102

Coba atur breakpoint simbolis -[NSObject(NSObject) doesNotRecognizeSelector:]. Cukup klik [+]di sudut kiri bawah dari Breakpoint Navigator untuk menambahkan titik putus. Kemudian klik 'Add Symbolic Breakpoint'. Mereproduksi kerusakan Anda sekarang akan memberi Anda gagasan yang lebih baik di bagian mana dalam kode Anda masalah terjadi.

masukkan deskripsi gambar di sini

dbart
sumber
17
Bisa juga menambahkan breakpoint pengecualian .
rebello95
1
Menyelamatkan hariku, bro.
AntiMoron
1
Terima kasih ini sangat berguna
Mohd Sadham
35

Anda dapat dengan mudah melacak kerusakan tersebut menggunakan Exception Breakpoints .

Buka Breakpoint Navigatordan tambahkan

masukkan deskripsi gambar di sini

Setelah Anda menambahkan Exception Breakpoint, opsi akan terbuka untuk memilih Exception.

masukkan deskripsi gambar di sini

Pilih Objective-C .

Jalankan kode dan hancurkan aplikasi, breakpoint akan menghentikan Anda ke titik di mana kode tersebut mogok.

Vatsal K
sumber
Itu terjadi pada AppDelegate baris 1. Sekarang apa? :(
Daniel Springer
Dapatkah Anda menunjukkan beberapa kode Anda yang tertulis di AppDelegate? Di mana itu menghentikan breakpoint. Dan juga lognya.
Vatsal K
itu berhenti di baris 1, di mana delegasi aplikasi diumumkan
Daniel Springer
Ada beberapa kasus di mana itu berhenti, karena beberapa kerangka kerja, Tapi jangan khawatir tentang itu Anda mungkin perlu menekan tombol lanjutkan selama 3-4 kali untuk menjalankan aplikasi.
Vatsal K
Itu bukan kesalahan dalam kasus seperti itu, Beberapa kerangka kerja lama menyebabkan masalah semacam ini. Coba dengan memperbarui kerangka kerja lama Anda ke yang baru / diperbarui. Itu seharusnya menyelesaikan masalah.
Vatsal K
30

Langkah penting pertama adalah menganalisis pesan kesalahan:

[UITableViewCellContentView image]: unrecognized selector sent to instance

Ini memberitahu Anda bahwa "pesan" imagetelah "dikirim" ke objek kelas UITableViewCellContentView. (Dengan kata lain, telah dilakukan upaya untuk memanggil metode imagepada objek kelas UITableViewCellContentView.)

Hal pertama yang harus ditanyakan adalah "Apakah ini masuk akal sama sekali?" Mungkin kelas bernama memiliki Imagemetode, tetapi bukan imagemetode, dan nama metode yang salah digunakan pada panggilan tersebut. Atau mungkin metode bernama someMethod:someParm:, tetapi kelas mengimplementasikan someMethod:someParm:anotherParm:, yang berarti bahwa parameter dihilangkan saat panggilan.

Paling sering, kelas bernama tidak memiliki metode apa pun bahkan samar-samar menyerupai metode bernama, yang berarti bahwa entah bagaimana pointer ke objek yang salah digunakan dalam panggilan yang gagal.

Misalnya, seseorang mungkin melakukan:

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

Dan dapatkan kesalahan di sepanjang baris:

[__NSDictionaryI objectAtIndex:] unrecognized selector sent to instance

karena objek yang diambil myDictionarysebenarnya adalah NSDictionary, bukan NSArray yang diharapkan.

Sayangnya, yang paling membingungkan adalah ketika kesalahan semacam ini terjadi jauh di dalam kode sistem UI, bukan di kode Anda sendiri. Hal ini dapat terjadi saat Anda mengirimkan objek yang salah ke antarmuka sistem, atau mungkin mengonfigurasi kelas yang salah di Interface Builder atau di mana pun.

Licks panas
sumber
6

Alasan lain yang mungkin adalah bahwa objek asli dihancurkan dan kemudian objek lain dialokasikan pada alamat memori yang sama. Kemudian kode Anda mengirim pesan, mengira itu masih memiliki penunjuk ke objek lama, dan Objective-C melontarkan pengecualian karena objek baru tidak memahami pesan itu.

Untuk mendiagnosis masalah ini, jalankan Profiler dengan deteksi 'Zombies'.

Bryan
sumber
2

Swift 5.0.0

Anda dapat menggunakan Introspeksi untuk mengetahui apakah objek merespons pemilih tertentu atau tidak ..

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

Hanya jika benar kode itu akan berfungsi .. jika tidak maka pasti akan macet

Saranjith
sumber
1

Dalam skenario ini, saya merasa terbantu dengan melihat dua hal

  1. Tumpukan panggilan
  2. Variabel lokal (dan tipenya) di setiap bingkai tumpukan

Ketika saya mengalami kesalahan ini, biasanya karena saya mengirim pesan ke instance Tipe A, ketika saya mengharapkan Tipe B.

Dalam skenario khusus ini, Anda mungkin tidak memenuhi persyaratan kelas induk (mengingat kemungkinan besar instance ItemTableViewCell Anda mewarisi).

Bisakah Anda menunjukkan kepada kami kode untuk kelas ItemTableViewCell Anda?

ABC
sumber
1

Anda dapat menggunakan kode berikut untuk mendeklarasikan variabel:

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
sumber
0

Saya memiliki masalah yang sama, dan ini berhasil untuk saya:

Ganti isEqual di SKScene Anda:

- (BOOL)isEqual:(id)other {

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

Anda harus lulus indexPathuntuk mendeklarasikan objek sel tableview.

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

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

    return cell
}
Rohit Parsana
sumber