美文网首页
Swift-toString

Swift-toString

作者: chernyog | 来源:发表于2017-07-10 15:20 被阅读427次

    前言

    众所周知,很多编程语言都有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; 
    

    代码分析

    • 可以打印继承自BaseModel的对象信息
    • 每次打印的时候都会获取所有属性!

    代码优化

    优化方案

    使用缓存(这里使用的是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)
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Swift-toString

          本文链接:https://www.haomeiwen.com/subject/eszyhxtx.html