Swift-toString

2017-07-10  本文已影响427人  chernyog

前言

众所周知,很多编程语言都有toString()方法,旨在很简单地输出对象信息,当然Swift也有类似的方法 - description属性。如果想个性的打印对象信息,就需要重写description属性。

需求

打印任一对象的属性信息(实际工作中,一般是在开发阶段中打印 model 信息,这里就按这种需求举例)

阅读前的准备

假设已经熟悉 Swift 反射相关知识(可以参考我的另一篇文章:Swift-Reflection)

主要代码

class BaseModel: NSObject {
    override var description: String {
        // 获取属性列表
        let clazz: NSObject.Type = type(of: self)
        // 通过反射获取对象的所有属性
        if let propertyList: [[String : Any]] = SwiftReflectionTool.propertyList(clazz: clazz) {
            var result = "[\(type(of: self))] ==> "
            for dict in propertyList {
                let (key, _) = SwiftReflectionTool.convert(dict: dict)
                let value = self.value(forKeyPath: key) ?? ""
                let subStr = "\(key)=\(value); "
                // 拼接字符串
                result += subStr
            }
            return result
        }
        return ""
    }
}

// 控制台打印结果如下:
[Book] ==> title=XXX从入门到放弃; author=cy; numberOfPages=250; released=2017-07-10 07:00:06 +0000; isSaled=1; 

代码分析

代码优化

优化方案

使用缓存(这里使用的是PINCache内存缓存方案)!

主要代码

BaseKitModel.swift

class BaseKitModel: NSObject {
    override init() {
        super.init()
        // 设置唯一标识
        BaseKitModelService.id = "\(type(of: self))"
    }
    override var description: String {
        // 获取属性列表
        let propertyList: [[String : Any]]?
        if let cacheList = BaseKitModelService.propertyList, cacheList.count > 0 {
            // 从缓存中取
            propertyList = cacheList
        } else {
            // 动态获取
            propertyList = SwiftReflectionTool.propertyList(obj: self)
            BaseKitModelService.propertyList = propertyList
        }
        if let propertyList = propertyList {
            var result = "[\(BaseKitModelService.id ?? "")] ==> "
            for dict in propertyList {
                let (key, _) = SwiftReflectionTool.convert(dict: dict)
                let value = self.value(forKeyPath: key) ?? ""
                let subStr = "\(key)=\(value); "
                result += subStr
            }
            return result
        }
        return ""
    }
    
    deinit {
        print("Deinit: \(NSStringFromClass(type(of: self)))")
        // 对象释放时,清除缓存
        BaseKitModelService.cache.removeAllObjects()
    }
}

BaseKitModelService.swift

open class BaseKitModelService {
    static let sharedInstance = BaseKitModelService()
    private init() {}
    
    static let cache = PINMemoryCache.shared()
    static var id: String? {
        didSet {
            KEY = "BaseKitModelServiceKey4\(id ?? "")"
        }
    }
    
    private static var KEY = "BaseKitModelServiceKey4"
    
    static var propertyList: [[String : Any]]? {
        get {
            let key: String? = KEY  // 多此一举! 目的:为了不默认调用另一个无返回值的重载方法!
            if let list = cache.object(forKey: key) as? [[String: Any]] {
                return list
            }
            return nil
        }
        set {
            if let value = newValue {
                cache.setObject(value as NSCoding, forKey: KEY)
            } else {
                cache.removeObject(forKey: KEY)
            }
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读