为什么会出现未捕获的异常?

Why is there an uncaught exception?

我在使用 Swift 时遇到了一些错误,当我尝试了其他 Stack Overflow 帖子中列出的解决方案时,我遇到了其他错误。我得到的第一个错误是 NSForwarding:警告:class 'h2.Items' 的对象 0x7dc4ca30 没有实现 methodSignatureForSelector:——麻烦在前 无法识别的选择器 -[h2.Items initWithCoder:]

然后我更新了我的代码以添加 "NSObject",当我这样做时我收到以下错误:

由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'-[h2.Items initWithCoder:]:无法识别的选择器发送到实例 0x79069250'

我不确定从这里到哪里去。我一直在关注 http://shrikar.com/blog/2015/01/17/uitableview-and-uitableviewcell-customization-in-swift/

上的教程

并尝试了 Got Unrecognized selector -replacementObjectForKeyedArchiver: crash when implementing NSCoding in Swift

中的解决方案

有没有人有任何额外的建议?

我的代码是:

import CloudKit
import UIKit
import Foundation

class Items: NSObject  
{
    class Entry 
    {
        var filename : String
        init(fname : String)
        {
            self.filename = fname
        }
    }

    var pics = [
        Entry(fname: "circle.png")
    ]
}

这是调用 class:

的代码
var items = Items()

override func viewDidLoad() {
    super.viewDidLoad()
}


override func numberOfSectionsInTableView(tableView: UITableView) -> Int {

    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return items.pics.count
}


override func tableView(tableVIew: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as TableViewCell

    let entry = items.pics[indexPath.row]
    let image = UIImage(named: entry.filename)
    cell.anotherSelfie.image = image


    return cell
}

}

这里是单元格的代码:

class TableViewCell: UITableViewCell {

@IBOutlet var anotherSelfie: UIImageView!


override func awakeFromNib() {
    super.awakeFromNib()

}

override func setSelected(selected: Bool, animated: Bool) {
   super.setSelected(selected, animated: animated)
}


        }

这个问题中没有任何内容会导致您描述的错误。我使用了您的代码,即使没有 NSObject 参考,它也能正常工作。问题出在别处。

肯定还有其他事情您没有与我们分享(例如,进行状态恢复,自己调用 NSKeyedArchiver,可能不小心将 Items 引用连接到情节提要中的某些内容, ETC。)。但是,无论您在做什么,它都会尝试调用 init(coder aDecoder: NSCoder)(又名 initWithCoder)。

所以,你有两个选择:

  • 您应该确定是什么触发了 initWithCoder 为这个 Items 对象调用。从那里,您可以决定是否真的需要完成这项工作。

  • 如果您得出结论认为您需要 initWithCoder(也可能需要 encodeWithCoder,具体取决于调用它的内容),您可以继续并制作此 class NSCoding 通过实施

    合规
    init(coder decoder: NSCoder) { ... }
    func encodeWithCoder(_ encoder: NSCoder) { ... }
    

    请参阅 归档和序列化编程指南中的 Encoding and Decoding Objects 这是为 Objective-C 编写的,但在 [=60] 中的想法是相同的=].

    顺便说一句,如果您得出结论认为您确实需要使 Items 符合 NSCoding,那么您很可能也必须为 Entry 做这件事。

但我只会在确定需要此内容并确认我的应用程序确实需要此内容后,才会努力遵守 NSCoding

坦率地说,除非您从事档案或国家恢复工作,否则如果您需要走那条路,我会感到非常惊讶。您正在关注的教程没有参与其中,我在这里看不到任何暗示这里有必要的东西。

如果您无法找到触发此 initWithCoder 的对 Items 的意外引用,我可能建议您从头开始该项目,看看是否可以重现该问题。如果您能够在空白项目中重现该问题,请与我们分享您为证明该问题所遵循的具体步骤,因为我无法重现您描述的问题。我们需要 MCVE,但我无法用目前提供的代码重现您描述的问题。