注意:
运行时
是OC
的,其实Swift``官方
并不是太提倡
, 需要在class
前加上@objcMembers
声明该对象是OC
的,不然获取不了对象属性列表
使用
import UIKit
class ViewController: UIViewController {
let p = UserInfo()
override func viewDidLoad() {
super.viewDidLoad()
p.name = "yusong"
p.age = 20
// p.professional = "ios"
p.address = "jiaotukeji"
}
// MARK: - 归档
@IBAction func archiveclick(_ sender: Any) {
UserTool.saveUser(p)
}
// MARK: - 解档
@IBAction func solutionFileClick(_ sender: Any) {
let p = UserTool.getUser()
guard let user = p else{
print("文件不存在")
return
}
print(user.name,user.address ,user.age ,user.professional)
}
// MARK: - 删档
@IBAction func removeClick(_ sender: Any) {
UserTool.removeUser()
}
}
实现
import UIKit
@objcMembers class UserInfo: NSObject,NSCoding {
// MARK: - 属性
var name :String?
var address :String?
var professional:String = "123" // 给定初始值
var age :Int = 0
// MARK: - 初始方法
override init() {
super.init()
}
// MARK: - 归档
func encode(with aCoder: NSCoder) {
for Strname in getAllPropertys() {
let value = self.value(forKey: Strname)
aCoder.encode(value, forKey: Strname)
}
}
// MARK: - 解档
internal required init?(coder aDecoder: NSCoder){
super.init()
for Strname in getAllPropertys() {
let value = aDecoder.decodeObject(forKey: Strname)
//利用kvc给属性赋值
setValue(value, forKeyPath: Strname)
}
}
// MARK: - 获取属性数组
func getAllPropertys()->[String]{
// 这个类型可以使用CUnsignedInt,对应Swift中的UInt32
var count: UInt32 = 0
let properties = class_copyPropertyList(self.classForCoder, &count)
var propertyNames: [String] = []
// Swift中类型是严格检查的,必须转换成同一类型
for i in 0..<Int(count) {
// UnsafeMutablePointer<objc_property_t>是可变指针,因此properties就是类似数组一样,可以通过下标获取
let property = properties![i]
let name = property_getName(property)
// 这里还得转换成字符串
let strName = String(cString: name)
propertyNames.append(strName);
}
// 不要忘记释放内存,否则C语言的指针很容易成野指针的
free(properties)
return propertyNames;
}
// MARK: - 获取对应属性的值 没有侧返回nil
func getValueOfProperty(property:String)->AnyObject?{
let allPropertys = self.getAllPropertys()
if(allPropertys.contains(property)){
return self.value(forKey: property) as AnyObject
}else{
return nil
}
}
}
class UserTool{
// MARK: - 归档路径设置
static private var Path: String{
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last!
return (path as NSString).appendingPathComponent("account.plist")
}
/// 存档
static func saveUser(_ user: NSObject){
NSKeyedArchiver.archiveRootObject(user, toFile: Path)
}
/// 获取归档模型
static func getUser()-> UserInfo? {
let user = NSKeyedUnarchiver.unarchiveObject(withFile: Path) as? UserInfo
return user
}
/// 删除归档
static func removeUser() {
if FileManager.default.fileExists(atPath: Path){
try! FileManager.default.removeItem(atPath: Path) // 删除文件
}else{
}
}
}