问题描述
我有一个Swift类,该类存储当前应用于视图控制器的不同类型的过滤器。我想使用状态还原来保存此设置,这样,即使用户离开应用程序并返回,即使该应用程序已被系统终止,过滤器也会被还原。
我不确定执行此操作的最佳方法是什么。我相信这与Codable
有关,但是如何使它与UIViewController编码/解码一起使用。
首先,课程:
@objcmembers class CJDataViewControllerFilters: NSObject {
var selecteddatefilters = [String: Array<Date>]()
var selectedTitleFilters = [NSManagedobject]()
var customFilterPredicate: nspredicate?
var customFilterName: String?
let filterStyle: SectionStyle
init(style: SectionStyle) {
self.filterStyle = style
super.init()
}
}
UIViewController(仍在Objective-C中):
@interface DiaryViewController : UIViewController {
@property (nonatomic,strong) CJDataViewControllerFilters *dataFilters;
}
并恢复通话状态:
- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
[super encodeRestorableStateWithCoder:coder];
[coder encodeObject:self.dataFilters forKey: @"DataFiltersDiary"];
}
仅当应用程序进入后台时,这样做会崩溃:
2020-08-15 11:37:55.470081-0700 CJournal [11367:6382501] -[XYZApp.CJDataViewControllerFilters encodeWithCoder:]:无法识别的选择器已发送到实例0x6000014cb640
因此,我向Codable
类添加了CJDataViewControllerFilters
作为协议,并添加了基本一致性:
@objcmembers class CJDataViewControllerFilters: NSObject,Codable {
func encode(to encoder: Encoder) throws {
print("CJDataViewControllerFilters: encode")
}
required init(from decoder: Decoder) throws{
print("init(from decoder)")
}
}
由于相同的原因它仍然崩溃。
如何最好地解决此问题?是否有其他实施方法?另外,如何手动编码/解码诸如nspreciate和NSManagedobjects数组之类的东西?
Codable
上的大多数示例都涉及JSON编码/编码,我在这里不需要(我认为),因此希望得到一个答案。
解决方法
编码和解码NSObject的方法是使其符合NSCoding(如今为NSSecureCoding)。现在,您可以在节省时间时使用键控存档程序将其放入编码器中,并在还原时使用键控取消存档器将其从编码器中移除。
大多数内置类型(例如NSPredicate)已经符合NSSecureCoding的要求,因此总体上解决了该问题。
如果您的类型具有并非免费桥接到NSCoding类型的Codable属性(如String到NSString),则可以使用NSCoder子类方法encodeEncodable(_:forKey:)
和decodeDecodable(_:forKey:)
对它们进行编码。