Swift控制全局的单例模式
Swift控制全局的单例模式

Swift控制全局的单例模式

在iOS中使用StoreKit2时,发现对应的代码存在Static静态的实例代码:

import StoreKit
@available(iOS 15.0, *)
class IAPManager {
    static let shared = IAPManager()    // 单实例模式
    ...
}

接下来就是学习和掌握这个单例的模式。

单例模式是什么?

单例模式 (Singleton Pattern) 是一种设计模式,确保在应用程序中某个类只有一个实例,并提供一个全局访问点来使用该实例。这种模式通常用于管理共享资源或控制全局状态。

单例模式的特点

1、唯一实例:

单例模式会限制类的实例化,使得整个程序在运行过程中只能创建一个实例对象。即使在不同的地方尝试创建实例,都会返回相同的对象。

2、全局访问:

单例实例可以通过一个静态方法或属性访问。程序的任何部分都可以使用这个全局访问点来获取单例对象。

3、控制资源使用:

单例模式对于管理有限资源很有用,比如数据库连接、线程池、配置管理器等。在这些情况下,使用一个实例对象而不是多个实例可以节省资源和保持一致性。

使用场景

配置管理:应用程序的配置通常是唯一的,可以用单例来管理。

日志记录:日志记录对象通常需要被全局访问,使用单例可以确保所有的日志操作都写入同一个文件。

网络管理:网络请求管理器通常需要被全局访问,以保持请求状态的一致性。

数据库连接:确保只有一个数据库连接实例,以避免连接资源浪费。

代码样例

class ConfigurationManager {
    static let shared = ConfigurationManager() // 创建唯一实例
    private init() {} // 将初始化方法私有化,防止外部创建新实例

    var configValue: String = "Default Configuration"
}

// 使用单例实例
ConfigurationManager.shared.configValue = "New Configuration"
print(ConfigurationManager.shared.configValue) // 输出 "New Configuration"

在上面的例子中:

static let shared = ConfigurationManager() 创建了 ConfigurationManager 的唯一实例。

private init() 确保无法从外部创建 ConfigurationManager 的新实例。

通过 ConfigurationManager.shared 可以在应用的任何地方访问并操作该唯一实例。

单例模式的优缺点

优点

控制实例数量:确保一个类只有一个实例,节省系统资源。

全局访问:提供一个全局访问点,方便调用和管理。

惰性初始化:实例通常在第一次被调用时才创建,避免程序启动时占用资源。

缺点

全局状态可能导致隐式依赖:由于实例是全局的,程序中各个部分都可能依赖它,这会增加代码的耦合性,难以进行模块化和测试。

难以扩展:由于单例模式严格控制实例的数量,因此在需要多实例的情况下,不容易扩展。

总结

单例模式确保类在整个程序中只有一个实例,同时提供一个全局访问点。这种模式非常适合用来管理共享资源或控制全局状态,但在使用时也要小心过度依赖,避免引入隐式依赖和耦合。

前面提到的iOS使用Store Kit2时,使用单例模式可以保证应用内购(IAP)可以被集中处理,避免多次创建实例。因为每次处理应用内购都会创建一个新的实例,占用更多的内存和资源,这里使用单例模式可以避免这种情况。同时也不需要在每个需要内购的页面创建新的实例,直接使用IAPManager.shard即可。

还需要注意的是,单例模式多用于Class,因为类具有引用类型的特性,可以确保不同地方都指向同一个实例,而在Struct结构中也可以实现单例模式。

struct Logger {
    static let shared = Logger()
    private init() {} // 私有化初始化方法,防止创建新实例

    func log(message: String) {
        print("Log: \(message)")
    }
}

在使用方面,单例模式只有在第一次访问时才创建。这跟懒加载(lazy loading)有关。因为shared是一个静态常量,静态常量在Swift是延迟初始化的,意味着只有它在被使用时才分配内存,这种机制可以节省启动时的资源开销。

static let shared = IAPManager()    // 单实例模式

因此,IAPManager的实例不会在诚信启动时立即创建,只有在第一次调用IAPManager.shared时,才会真正的创建这个对象。

调用单例非常简单,因为shared是一个静态属性,可以直接通过类名访问它:

// 调用 `IAPManager` 的单例实例
await IAPManager.shared.fetchSingleProduct()

每次调用IAPManager.shared,都会得到同一个IAPManager实例,在不同的视图控制器和模块中使用它,也会共享相同的状态。

值得注意的是,当我们尝试使用单例模式时,还需要使用《Swift私有化初始化方法》,这是因为我们需要将构造方法私有化,才能避免从外部调取构造方法并创建多个重复的实例。

可能还涉及Static的知识点,可以查看《static静态方法的实际运用》这篇文章补充。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注