美文网首页
Swift单例实践 2023-05-20 周六

Swift单例实践 2023-05-20 周六

作者: 勇往直前888 | 来源:发表于2023-05-20 07:31 被阅读0次

简介

用户信息一般都要用,一般一开始从网络读取,然后就缓存起来,随用随取。

缓存类型选择

  • 可以用磁盘缓存,没有问题;

  • 也可以用内存缓存。APP重启之后,就应该从网络去取,时间太长,大概率会有修改,需要更新一下。本次就存在内存缓存中

单例

  • 内存缓存,一般用单例来表示

  • 习惯上,单例都会取名XXXManager

  • Swift的单例网上有好多种写法,选择了最简单的一种

// MARK: - 单例
final class UserServiceManager {
    /// 单例实例
    /// UserServiceManager.sharedInstance.就是单例的用法
    static let sharedInstance = UserServiceManager()
}

静态方法

直接调用单例,一般都有XXX.sharedInstance.的样子,感觉有点啰嗦,所以考虑再封装一层,提供静态方法,直接XXX.就可以了

封装方式

  • OC一般分开两个文件,但是Swift感觉只要一个文件就可以了

  • 对外的接口用struct,命名用XXXService;单例用class,放在同一个文件中,命名为XXXServiceManager

  • 单例XXXServiceManager相当于具体实现,结构体XXXService相当于对外接口
    所以访问参数,单例用fileprivate,结构体用public

import Foundation

// MARK: - 公共接口
struct UserService {
    /// 判断用户信息是否为空
    public static func isUserInfoNotEmpty() -> Bool {
        if let userInfo = getUserInfo(), let userId = userInfo.userId {
            return (userId > 0)
        } else {
            return false
        }
    }
    
    /// 保存用户信息;设置为nil,就是清空
    public static func saveUserInfo(_ userInfo: UserInfoModel?) {
        UserServiceManager.sharedInstance.saveUserInfo(userInfo)
    }
    
    /// 读取用户信息
    public static func getUserInfo() -> UserInfoModel? {
        return UserServiceManager.sharedInstance.getUserInfo()
    }
}

// MARK: - 单例
final class UserServiceManager {
    /// 单例实例
    /// UserServiceManager.sharedInstance.就是单例的用法
    fileprivate static let sharedInstance = UserServiceManager()
    
    // MARK: - 接口
    fileprivate func saveUserInfo(_ userInfo: UserInfoModel?) {
        self.userInfo = userInfo
    }
    
    fileprivate func getUserInfo() -> UserInfoModel? {
        return self.userInfo
    }
    
    
    // MARK: - 属性
    private var userInfo: UserInfoModel? = nil
}

存取方法

  • 默认从缓存中取就可以了,

  • 如果缓存中没有,那么就需要访问网络,

  • 如果怀疑有更新,不想取缓存中的值,直接访问网络,那么就提供一个参数useCache来控制

  • 每次网络数据返回,如果不为空,就缓存在内存缓存中,随时备用

/// User模块接口封装
struct UserApi {
    /// 获取用户信息;默认从内存缓存取;缓存没有,才访问网络;useCache = false, 从网络取
    public static func asyncGetUserInfo(useCache: Bool = true) async -> UserInfoModel? {
        if (useCache && UserService.isUserInfoNotEmpty()) {
            return UserService.getUserInfo()
        } else {
            let moYaModel = await MoyaNetworkManager.sharedInstance.asyncRequest(command: .userGetUserInfo)
            if let userInfo = UserInfoModel.deserialize(from:moYaModel.data as? Dictionary<String, Any>) {
                /// 保存到内存中缓存起来
                UserService.saveUserInfo(userInfo)
                
                return userInfo
            } else {
                return nil
            }
        }
    }
}

使用

使用的时候,不需要关心数据来自哪里,直接用就好了。如果想更新,通过useCache控制一下就可以了

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.setNavigationBarHidden(true, animated: animated)
        
        Task {
            if let data = await UserApi.asyncGetUserInfo(useCache: true) {
                debugPrint(data)
            }
        }
    }

相关文章

网友评论

      本文标题:Swift单例实践 2023-05-20 周六

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