Swift 3 NSCoder 无法识别的选择器发送到实例
Posted
技术标签:
【中文标题】Swift 3 NSCoder 无法识别的选择器发送到实例【英文标题】:Swift 3 NSCoder unrecognized selector sent to instance 【发布时间】:2017-06-30 23:45:04 【问题描述】:我正在尝试将自定义类的列表保存到用户默认值,并且在保存时我不断收到“无法识别的选择器发送到实例”错误。从用户默认值获取数组时我没有问题。
这是我用来保存到用户默认值的代码。
let userDefaults = UserDefaults.standard
userDefaults.set(NSKeyedArchiver.archivedData(withRootObject: visitors), forKey: "signedInUsers")
userDefaults.synchronize()
visitors 是一个访问者对象数组。
这是我的访客类。
class Visitor: NSObject
var name: String = ""
var contactEmail: String = ""
var company: String = ""
var picture: UIImage = UIImage()
var signature: UIImage = UIImage()
var timeIn: String = ""
var timeOut: String = ""
var signedOut: Bool = false
var otherQuestionsWithAnswers: [String] = []
// MARK: NSCoding
override init()
super.init()
init(name: String, contactEmail: String, company: String, picture: UIImage, signature: UIImage,timeIn: String,timeOut: String,signedOut: Bool,otherQuestionsWithAnswers: [String])
self.name = name
self.contactEmail = contactEmail
self.company = company
self.picture = picture
self.signature = signature
self.timeIn = timeIn
self.timeOut = timeOut
self.signedOut = signedOut
self.otherQuestionsWithAnswers = otherQuestionsWithAnswers
required convenience init?(coder decoder: NSCoder)
guard let name = decoder.decodeObject(forKey: "name") as? String,
let contactEmail = decoder.decodeObject(forKey: "contactEmail") as? String,
let company = decoder.decodeObject(forKey: "company") as? String,
let timeOut = decoder.decodeObject(forKey: "timeOut") as? String,
let timeIn = decoder.decodeObject(forKey: "timeIn") as? String,
let picture = decoder.decodeObject(forKey: "picture") as? UIImage,
let signature = decoder.decodeObject(forKey: "signature") as? UIImage,
let otherQuestionsWithAnswers = decoder.decodeObject(forKey: "otherQuestionsWithAnswers") as? [String],
let signedOut = decoder.decodeObject(forKey: "signedOut") as? Bool
else return nil
self.init(
name: name,
contactEmail: contactEmail,
company: company,
picture: picture,
signature: signature,
timeIn: timeIn,
timeOut: timeOut,
signedOut: signedOut,
otherQuestionsWithAnswers: otherQuestionsWithAnswers
)
func encodeWithCoder(coder: NSCoder)
coder.encode(name, forKey: "name")
coder.encode(contactEmail, forKey: "contactEmail")
coder.encode(company, forKey: "company")
coder.encode(picture, forKey: "picture")
coder.encode(signature, forKey: "signature")
coder.encode(timeIn, forKey: "timeIn")
coder.encode(timeOut, forKey: "timeOut")
coder.encode(signedOut, forKey: "signedOut")
coder.encode(otherQuestionsWithAnswers, forKey: "otherQuestionsWithAnswers")
感谢您的帮助。
编辑:
将类更改为此修复它。
import Foundation
import UIKit
// a question that the user has to answer
class Visitor: NSObject, NSCoding
var name: String = ""
var contactEmail: String = ""
var company: String = ""
var picture: UIImage = UIImage()
var signature: UIImage = UIImage()
var timeIn: String = ""
var timeOut: String = ""
var signedOut: Bool = false
var otherQuestionsWithAnswers: [String] = []
// MARK: NSCoding
override init()
super.init()
init(name: String, contactEmail: String, company: String, picture: UIImage, signature: UIImage,timeIn: String,timeOut: String,signedOut: Bool,otherQuestionsWithAnswers: [String])
self.name = name
self.contactEmail = contactEmail
self.company = company
self.picture = picture
self.signature = signature
self.timeIn = timeIn
self.timeOut = timeOut
self.signedOut = signedOut
self.otherQuestionsWithAnswers = otherQuestionsWithAnswers
required init(coder decoder: NSCoder)
name = decoder.decodeObject(forKey: "name") as! String
contactEmail = decoder.decodeObject(forKey: "contactEmail") as! String
company = decoder.decodeObject(forKey: "company") as! String
timeOut = decoder.decodeObject(forKey: "timeOut") as! String
timeIn = decoder.decodeObject(forKey: "timeIn") as! String
if let pictureTest = decoder.decodeObject(forKey: "picture") as? UIImage
picture = pictureTest
else
picture = UIImage()
if let sigTest = decoder.decodeObject(forKey: "picture") as? UIImage
signature = sigTest
else
signature = UIImage()
otherQuestionsWithAnswers = decoder.decodeObject(forKey: "otherQuestionsWithAnswers") as! [String]
signedOut = decoder.decodeBool(forKey: "signedOut")
public func encode(with aCoder: NSCoder)
aCoder.encode(name, forKey: "name")
aCoder.encode(contactEmail, forKey: "contactEmail")
aCoder.encode(company, forKey: "company")
aCoder.encode(picture, forKey: "picture")
aCoder.encode(signature, forKey: "signature")
aCoder.encode(timeIn, forKey: "timeIn")
aCoder.encode(timeOut, forKey: "timeOut")
aCoder.encode(signedOut, forKey: "signedOut")
aCoder.encode(otherQuestionsWithAnswers, forKey: "otherQuestionsWithAnswers")
【问题讨论】:
没有被识别的特定选择器是什么?请包含您看到的完整错误消息。 好问题。同样的问题。不错的代码。期待看到这个伟大问题的答案。 @ItaiFerber 说什么选择器无法识别? 你用的是什么swift版本? 'NSInvalidArgumentException', reason: '-[Visitor_Manager.Visitor encodeWithCoder:]: unrecognized selector sent to instance 0x14e33400' swift 3. 删除该功能后仍然说使用编码器进行编码 【参考方案1】:您用于编码的函数不正确,必须是 func encode(with aCoder: NSCoder)
而不是 func encodeWithCoder(coder: NSCoder)
,因此请更改它并按预期工作
public func encode(with aCoder: NSCoder)
aCoder.encode(name, forKey: "name")
aCoder.encode(contactEmail, forKey: "contactEmail")
aCoder.encode(company, forKey: "company")
aCoder.encode(picture, forKey: "picture")
aCoder.encode(signature, forKey: "signature")
aCoder.encode(timeIn, forKey: "timeIn")
aCoder.encode(timeOut, forKey: "timeOut")
aCoder.encode(signedOut, forKey: "signedOut")
aCoder.encode(otherQuestionsWithAnswers, forKey: "otherQuestionsWithAnswers")
希望对你有帮助
【讨论】:
嗯...似乎仍然无法正常工作。感谢回复 @VincentLandolfi 你清理了你的项目并重试了吗?【参考方案2】:您的访问者类应该首先从 NSObject 继承,然后是 NSCoding。如果没有 NSCoding,您将无法对自定义类进行编码和解码。这是我最近在项目中犯的一个错误,您的编码函数签名不正确。我相信这会解决这个问题。这是更正后的代码:
Swift 3 版本:-
class Visitor: NSObject, NSCoding
var name: String = ""
var contactEmail: String = ""
var company: String = ""
var picture: UIImage = UIImage()
var signature: UIImage = UIImage()
var timeIn: String = ""
var timeOut: String = ""
var signedOut: Bool = false
var otherQuestionsWithAnswers: [String] = []
func encode(with aCoder: NSCoder)
//... encode here
【讨论】:
似乎仍然无法正常工作。感谢您的回复。 你能在那个守卫语句上设置一个断点,看看它是否返回 nil 吗? 试过了,好像什么都没有以上是关于Swift 3 NSCoder 无法识别的选择器发送到实例的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3:发送到实例 Xcode 8 的无法识别的选择器 [重复]