我正在尝试将一组自定义对象保存到UserDefaults。我相信我现在应该正确保存,但是我继续收到“无法识别的选择器”错误。我认为这可能是因为我的自定义对象的两个部分是其他自定义对象的数组。我在这里做什么错了?
对象:
class SaleObject: NSObject, NSCoding {
//MARK: Properties
var ranges: [RangeObject]
var timberSaleName: String
var lbOperatorName: String
var lbOperatorID: String
var timberSaleID: Int
var ID: Int
var contracts: [ContractObject]
//MARK: Initialization
init(ranges: [RangeObject], timberSaleName: String, lbOperatorName: String, lbOperatorID: String, timberSaleID: Int, ID: Int ,contracts: [ContractObject]) {
//Initialize stored properties
self.ranges = ranges
self.timberSaleName = timberSaleName
self.lbOperatorName = lbOperatorName
self.lbOperatorID = lbOperatorID
self.timberSaleID = timberSaleID
self.ID = ID
self.contracts = contracts
}
required init?(coder aDecoder: NSCoder) {
self.ranges = (aDecoder.decodeObject(forKey: "ranges") as? [RangeObject])!
self.timberSaleName = (aDecoder.decodeObject(forKey: "timber_sale_name") as? String)!
self.lbOperatorName = (aDecoder.decodeObject(forKey: "lb_operator_name") as? String)!
self.lbOperatorID = (aDecoder.decodeObject(forKey: "lb_operator_id") as? String)!
self.timberSaleID = (aDecoder.decodeObject(forKey: "timber_sale_id") as? Int)!
self.ID = (aDecoder.decodeObject(forKey: "id") as? Int)!
self.contracts = (aDecoder.decodeObject(forKey: "contracts") as? [ContractObject])!
}
func encode(with aCoder: NSCoder) {
aCoder.encode(self.ranges, forKey: "ranges")
aCoder.encode(self.timberSaleName, forKey: "timber_sale_name")
aCoder.encode(self.lbOperatorName, forKey: "lb_operator_name")
aCoder.encode(self.lbOperatorID, forKey: "lb_operator_id")
aCoder.encode(self.timberSaleID, forKey: "timber_sale_id")
aCoder.encode(self.ID, forKey: "id")
aCoder.encode(self.contracts, forKey: "contracts")
}
}
保存尝试:
let userDefaults = UserDefaults.standard
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: self.saleArray)
userDefaults.set(encodedData, forKey: "sales")
错误:
2018-11-28 14:28:30.024768-0600 Load BOSS[14991:282335]
libMobileGestalt MobileGestalt.c:890: MGIsDeviceOneOfType is not
supported on this platform.
2018-11-28 14:28:30.362954-0600 Load BOSS[14991:282335] [MC] System
group container for systemgroup.com.apple.configurationprofiles path
is /Users/beauburchfield/Library/Developer/
CoreSimulator/Devices/4ED03814-DD8C-43F3-ABA7-
B5D0751161A0/data/Containers/Shared/SystemGroup/
systemgroup.com.apple.configurationprofiles
2018-11-28 14:28:30.364591-0600 Load BOSS[14991:282335] [MC] Reading
from private effective user settings.
2018-11-28 14:28:31.034136-0600 Load BOSS[14991:282394] -
[Load_BOSS.RangeObject encodeWithCoder:]: unrecognized selector sent
to
instance 0x600001bcc680
2018-11-28 14:28:31.037429-0600 Load BOSS[14991:282394] ***
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[Load_BOSS.RangeObject
encodeWithCoder:]: unrecognized selector sent to instance
0x600001bcc680'
*** First throw call stack:
(
0 CoreFoundation 0x000000010cbc51bb _ .
_exceptionPreprocess + 331
1 libobjc.A.dylib 0x000000010b73b735
objc_exception_throw + 48
2 CoreFoundation 0x000000010cbe3f44 -
[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 CoreFoundation 0x000000010cbc9ed6 ___forwarding___ + 1446
4 CoreFoundation 0x000000010cbcbda8 _CF_forwarding_prep_0 + 120
5 Foundation 0x000000010b182175 _encodeObject + 1230
6 Foundation 0x000000010b182aee -[NSKeyedArchiver _encodeArrayOfObjects:forKey:] + 439
7 Foundation 0x000000010b182175 _encodeObject + 1230
8 Load BOSS 0x000000010add0e2f $S9Load_BOSS10SaleObjectC6encode4withySo7NSCoderC_tF + 207
9 Load BOSS 0x000000010add128c $S9Load_BOSS10SaleObjectC6encode4withySo7NSCoderC_tFTo + 60
10 Foundation 0x000000010b182175 _encodeObject + 1230
11 Foundation 0x000000010b182aee -[NSKeyedArchiver _encodeArrayOfObjects:forKey:] + 439
12 Foundation 0x000000010b182175 _encodeObject + 1230
13 Foundation 0x000000010b18122e +[NSKeyedArchiver archivedDataWithRootObject:] + 156
14 Load BOSS 0x000000010adbf15a $S9Load_BOSS18MainViewControllerC14getJsonFromUrlyyFy10Foundation4DataVSg_So13NSURLResponseCSgs5Error_pSgtcfU_ + 15706
15 Load BOSS 0x000000010adbf43d $S9Load_BOSS18MainViewControllerC14getJsonFromUrlyyFy10Foundation4DataVSg_So13NSURLResponseCSgs5Error_pSgtcfU_TA + 13
16 Load BOSS 0x000000010adbf590 $S10Foundation4DataVSgSo13NSURLResponseCSgs5Error_pSgIegggg_So6NSDataCSgAGSo7NSErrorCSgIeyByyy_TR + 336
17 CFNetwork 0x000000010e0d9940 __75-[__NSURLSessionLocal taskForClass:request:uploadFile:bodyData:completion:]_block_invoke + 19
18 CFNetwork 0x000000010e0efb0c __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 172
19 Foundation 0x000000010b1a8f9e __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
20 Foundation 0x000000010b1a8ea5 -[NSBlockOperation main] + 68
21 Foundation 0x000000010b1a5c14 -[__NSOperationInternal _start:] + 689
22 Foundation 0x000000010b1abc4b __NSOQSchedule_f + 227
23 libdispatch.dylib 0x000000010f0ae595 _dispatch_call_block_and_release + 12
24 libdispatch.dylib 0x000000010f0af602 _dispatch_client_callout + 8
25 libdispatch.dylib 0x000000010f0b254d _dispatch_continuation_pop + 565
26 libdispatch.dylib 0x000000010f0b1927 _dispatch_async_redirect_invoke + 859
27 libdispatch.dylib 0x000000010f0c000a _dispatch_root_queue_drain + 351
28 libdispatch.dylib 0x000000010f0c09af _dispatch_worker_thread2 + 130
29 libsystem_pthread.dylib 0x000000010f49e70e _pthread_wqthread + 619
30 libsystem_pthread.dylib 0x000000010f49e435 start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException
答案 0 :(得分:1)
还必须为您的两个自定义对象实现NSCoding。其他一切都很好。
不过我想提一件事。
(aDecoder.decodeObject(forKey: "timber_sale_name") as? String)!
可以写为
aDecoder.decodeObject(forKey: "timber_sale_name") as! String
基本上含义相同,但更易于阅读。
答案 1 :(得分:1)
这里的崩溃
[Load_BOSS.RangeObject encodeWithCoder:]:无法识别的选择器已发送
给出了使根类符合的原因
class SaleObject: NSObject, NSCoding {
并不意味着您可以使用自定义对象(在您的情况下为RangeObject
)而不必使其也像
class RangeObject : NSObject, NSCoding {
强烈建议使用Codable
class SaleObject: Codable {
let ranges: [RangeObject]
let timberSaleName: String
let lbOperatorName: String
let lbOperatorID: String
let timberSaleID: Int
let ID: Int
let contracts: [ContractObject]
}
class RangeObject : Codable {
// add it's properties
}
使用方法:
let data = try? JSONEncoder().encode(obj) // obj may be single SaleObject or array
let obj = try? JSONDecoder().decode(SaleObject.self,from:data) // for data being array make it [SaleObject].self
答案 2 :(得分:1)
继续为其他两个自定义对象实现NSCoding。另外,将您的自定义对象的所有Integer上的decodeObject更改为decodeInteger,并从它们中删除“ as!Int”。然后,执行以下操作:
let userDefaults = UserDefaults.standard
let encodedData = NSKeyedArchiver.archivedData(withRootObject: self.saleArray)
userDefaults.set(encodedData, forKey: "sales")
要检索数据,请执行以下操作:
let newArray = NSKeyedUnarchiver.unarchiveObject(with: data as! Data) as! [SaleObject]
在工作之后,返回并研究Codable。享受吧!