一、对象的归档与解档需要遵循NSCoding和NSSecureCoding协议
其中NSSecureCoding协议更加安全
归档:把要保存的内容转为Data后保存到指定位置
解档:把指定位置的Data转为需要的对象
1.NSDictionary也可以直接进行归档和解档
2.归档的对象包括这个对象中的属性,它们所属类的都必须要遵守NSCoding协议才能归档和解档
2.自定义类的归档和解档
如果自定义的类对象要进行归档那么这个对象的属性所属的类也必须要遵守归档协议NSCoding
归档时不一定要直接归档到文件,还可以先将他们归档成NSData,然后将NSData进行存储,用的时候就用这个NSData解档
必须实现三个协议方法如下:
static var supportsSecureCoding: Bool {
return true
}
func encode(with coder: NSCoder) {
}
required init?(coder: NSCoder) {
}
二、归档协议方法调用如下:
fileprivate func handlePropertyEnCoder(_ acoder: NSCoder) {
let outCount = UnsafeMutablePointer<UInt32>.allocate(capacity: 0)
let propertys = class_copyPropertyList(self.classForCoder, outCount)
let count = Int(outCount[0])
for i in 0..<count {
if let property = propertys?[i] {
///获取属性名
guard let proName = String(utf8String: property_getName(property)) else {
continue
}
let propertyValue = self.value(forKey: proName)
if propertyValue != nil {
///获取属性值
guard let Attributes = property_getAttributes(property) else {
continue
}
///属性值转string
guard let AttributeString: String = String(utf8String: Attributes) else {
continue
}
let b:CharacterSet = NSCharacterSet(charactersIn: ",") as CharacterSet
let AttributeArray = AttributeString.components(separatedBy: b)
if AttributeArray.contains("R") {
///只读属性不做处理
}else {
// TODO: 注意
acoder.encode(propertyValue, forKey: proName)
}
}
}
}
///释放内存
// free(propertys)
}
三、解档协议方法调用如下:
fileprivate func handlePropertyDeCoder(_ acoder: NSCoder) {
var outCount: UInt32 = 0
let propertys = class_copyPropertyList(self.classForCoder, &outCount)
let count = Int(outCount)
for i in 0..<count {
if let property = propertys?[i] {
guard let propertyName = String(utf8String: property_getName(property)) else {
continue
}
let propertyValue = acoder.decodeObject(forKey: propertyName)
if propertyValue != nil {
///获取属性值
guard let attributes = property_getAttributes(property) else {
continue
}
guard let attributeString = String(utf8String: attributes) else {
continue
}
let b: CharacterSet = CharacterSet(charactersIn: ",") as CharacterSet
let attributeArray = attributeString.components(separatedBy: b)
if attributeArray.contains("R") {
//只读属性暂不读取
}else {
self.setValue(propertyValue, forKey: propertyName)
}
}
}
}
}
四、数据持久之UserDefaults
NSUserDefaults适合存储轻量级的本地数据。比如要保存一个登陆界面的数据,用户名、密码之类
NSUserDefaults存储的数据在应用程序内置的一个plist文件里
NSUserDefaults支持的数据格式有:NSNumber(Integer、Float、Double),NSString,NSDate,NSArray,NSDictionary,BOOL类型。
存储时,除NSNumber类型使用对应的类型意外,其他的都是使用setObject:forKey:
1、存储信息
/// 数据持久化到本地
func pr_saveToLocalData() {
if #available(iOS 11.0, *) {
///对象转为数据后写到指定位置
let infoData: Data? = try? NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding:false)
if infoData != nil {
PRUserDefaultsSaveData(infoData, pr_getClassName())
}
} else {
// Fallback on earlier versions
let infoData: Data? = NSKeyedArchiver.archivedData(withRootObject: self)
if infoData != nil {
PRUserDefaultsSaveData(infoData, String(utf8String: object_getClassName(self)))
}
}
}
2、获取信息
///加载本地数据
static func pr_loadLocalData() -> Any? {
let infoData: Data? = PRUserDefaultsGetObject(pr_getClassName()) as? Data
/// 把Data转为对象
if infoData != nil {
if #available(iOS 11.0, *) {
let info = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(infoData!) as? PRUserDataInfoProperty
return info
} else {
// Fallback on earlier versions
let info = NSKeyedUnarchiver.unarchiveObject(with: infoData!)
return info
}
}
return nil
}
3、清除信息
///清除缓存数据
func pr_clearLocalData() {
PRUserDefaultsRemoveObject(pr_getClassName())
}

1114

被折叠的 条评论
为什么被折叠?



