ฉันจะแก้ไขข้อผิดพลาด 'ตัวเลือกที่ไม่รู้จักที่ส่งไปยังอินสแตนซ์' ได้อย่างไร


101

ฉันกำลังสร้างมุมมองเซลล์ตารางแบบกำหนดเองสำหรับมุมมองตารางของฉัน หลังจากที่ฉันเชื่อมต่อมุมมองภาพของเซลล์ที่กำหนดเอง (ในสตอรี่บอร์ด) กับโค้ดของฉันอย่างรวดเร็วฉันได้รับข้อผิดพลาดต่อไปนี้

[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
หยุดเรียก [image] บน UITableViewCellContentView ซึ่งจะช่วยแก้ไขได้ แสดงรหัสที่ทำให้เกิดข้อขัดข้องนี้
Grzegorz Krukowski

1
ฉันคิดว่าคุณใช้ภาพบางภาพใน tableViewCell แต่ภาพนั้นอาจไม่อยู่ในชุดของคุณ
Nand Parikh

คำตอบ:


102

-[NSObject(NSObject) doesNotRecognizeSelector:]ลองตั้งค่าเบรกพอยต์สัญลักษณ์บน เพียงคลิก[+]ที่มุมล่างซ้ายของ Breakpoint Navigator เพื่อเพิ่มเบรกพอยต์ จากนั้นคลิก 'Add Symbolic Breakpoint' การจำลองข้อขัดข้องของคุณตอนนี้ควรให้ความคิดที่ดีขึ้นว่าปัญหาเกิดขึ้นที่ใดในโค้ดของคุณ

ป้อนคำอธิบายภาพที่นี่


17
ยังสามารถเพียงแค่เพิ่มจุดพักข้อยกเว้น
rebello95

1
บันทึกวันของฉันครับ
AntiMoron

1
ขอบคุณมันมีประโยชน์มาก
Mohd Sadham

35

Exception Breakpointsคุณสามารถติดตามการเกิดปัญหาดังกล่าวโดยใช้

เปิดBreakpoint Navigatorและเพิ่มไฟล์

ป้อนคำอธิบายภาพที่นี่

เมื่อคุณเพิ่มเบรกพอยต์ข้อยกเว้นตัวเลือกจะเปิดขึ้นเพื่อเลือกException.

ป้อนคำอธิบายภาพที่นี่

เลือกObjective-C.

เรียกใช้รหัสและทำให้แอปพลิเคชันหยุดทำงานเบรกพอยต์จะหยุดคุณจนถึงจุดที่โค้ดหยุดทำงาน


มันเกิดขึ้นใน AppDelegate บรรทัด 1 แล้วล่ะ? :(
Daniel Springer

คุณสามารถแสดงโค้ดบางส่วนที่เขียนใน AppDelegate ได้หรือไม่? ตำแหน่งที่หยุดเบรกพอยต์ชั่วคราว และยังมีท่อนไม้อีกด้วย
Vatsal K

หยุดชั่วคราวที่บรรทัดที่ 1 ซึ่งมีการประกาศตัวแทนของแอป
Daniel Springer

มีบางกรณีที่หยุดชั่วคราวเนื่องจากบางเฟรมเวิร์ก แต่ไม่ต้องกังวลว่าคุณอาจต้องกดปุ่มดำเนินการต่อ 3-4 ครั้งเพื่อเรียกใช้แอปพลิเคชัน
Vatsal K

นั่นไม่ใช่ข้อผิดพลาดในกรณีดังกล่าวเฟรมเวิร์กเก่าบางตัวทำให้เกิดปัญหาประเภทนี้ ลองอัปเดตเฟรมเวิร์กเก่าของคุณเป็นเฟรมเวิร์กใหม่ / อัพเดต ที่ควรแก้ไขปัญหา
Vatsal K

30

ขั้นตอนแรกที่สำคัญคือการวิเคราะห์ข้อความแสดงข้อผิดพลาด:

[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 ที่คาดไว้

น่าเสียดายที่ความสับสนที่สุดคือเมื่อข้อผิดพลาดประเภทนี้เกิดขึ้นในโค้ดระบบ UI แทนที่จะเป็นโค้ดของคุณเอง สิ่งนี้สามารถเกิดขึ้นได้เมื่อคุณส่งออบเจ็กต์ที่ไม่ถูกต้องไปยังอินเทอร์เฟซระบบหรืออาจกำหนดค่าคลาสผิดในตัวสร้างส่วนต่อประสานหรือที่ใดก็ตาม


6

อีกสาเหตุหนึ่งที่เป็นไปได้คือวัตถุดั้งเดิมถูกทำลายและจากนั้นวัตถุอื่นถูกจัดสรรที่ที่อยู่หน่วยความจำเดียวกัน จากนั้นรหัสของคุณจะส่งข้อความโดยคิดว่ายังมีตัวชี้ไปยังวัตถุเก่าและ Objective-C จะแสดงข้อยกเว้นเนื่องจากวัตถุใหม่ไม่เข้าใจข้อความนั้น

ในการวินิจฉัยปัญหานี้ให้เรียกใช้ Profiler ด้วยการตรวจจับ 'Zombies'


2

Swift 5.0

คุณสามารถใช้Introspectionเพื่อดูว่าวัตถุตอบสนองต่อตัวเลือกเฉพาะหรือไม่ ..

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

เฉพาะในกรณีที่รหัสนั้นเป็นจริงเท่านั้น .. ไม่งั้นจะพังแน่นอน


1

ในสถานการณ์เหล่านี้ฉันพบว่าการพิจารณาสองสิ่งนั้นเป็นประโยชน์

  1. โทรสแต็ก
  2. ตัวแปรโลคัล (และประเภท) ที่สแต็กเฟรมแต่ละเฟรม

เมื่อฉันมีข้อผิดพลาดนี้มักเป็นเพราะฉันส่งข้อความไปยังอินสแตนซ์ของ Type A เมื่อฉันคาดหวังประเภท B

ในสถานการณ์เฉพาะนี้คุณอาจไม่เป็นไปตามข้อกำหนดของคลาสหลัก (เนื่องจากอินสแตนซ์ของ 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

ฉันมีปัญหาเดียวกันและสิ่งนี้ใช้ได้ผลสำหรับฉัน:

แทนที่ isEqual ใน SKScene ของคุณ:

- (BOOL)isEqual:(id)other {

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

0

คุณต้องผ่านindexPathเพื่อประกาศวัตถุของเซลล์ tableview

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.