iOS Swift 设计模式|单例模式详解(概念+实战场景+示例代码+避坑指南)
📖 简介
在iOS中大型项目开发中,单例模式是使用频率最高、最简单且最重要的创建型设计模式。几乎所有企业级项目都会用到单例,例如网络管理、用户信息、全局配置等。本文通俗易懂讲解单例模式核心概念、底层原理、企业级标准写法、真实开发使用场景,附带可直接复用的完整示例代码,同时总结开发注意事项与避坑要点,适合新手学习、面试背诵、项目开发参考。
一、单例模式核心概念
1.1 什么是单例模式?
单例模式属于创建型设计模式,它可以保证:在整个App程序生命周期中,一个类有且仅有一个实例对象,并且对外提供统一的全局访问入口。
1.2 核心四大特征
-
唯一性:全局有且仅有一个实例,初始化仅执行一次;
-
全局性:项目任意页面、任意模块均可直接访问;
-
私有化构造器:禁止外部手动创建实例,杜绝重复初始化;
-
生命周期常驻:对象内存常驻,跟随App进程销毁而释放。
1.3 底层实现原理
Swift中单例底层实现逻辑十分简单:
-
使用静态常量生成唯一实例;
-
私有化
init\(\)构造方法,禁止外部创建; -
Swift静态常量天然线程安全,底层编译器保证初始化仅执行一次,无需手动加锁。
二、Swift企业级标准单例写法
2.1 最简通用写法(生产项目首选✅)
该写法简洁、线程安全、无冗余代码,是目前99% Swift中大型项目通用写法。
final class Manager {
// 1. 全局唯一静态实例
static let shared = Manager()
// 2. 私有化构造方法,禁止外部init创建
private init() {}
}
2.2 进阶加固写法(防止拷贝篡改)
为避免外部拷贝、复制单例对象,禁止拷贝方法,适合严谨商业项目:
final class UserManager {
static let shared = UserManager()
private init() {}
// 禁止拷贝
private func copy() {}
private func mutableCopy() {}
}
2.3 调用方式
无需初始化,全局任意位置直接点语法调用:
UserManager.shared.xxx
三、单例模式真实开发使用场景
单例不可滥用,仅适合全局唯一、需要频繁跨页面调用的管理类,以下为iOS企业级项目固定使用场景:
3.1 网络请求管理器
统一管理全局请求头、Token、超时时间、请求拦截、异常处理,避免重复创建请求会话,统一管控网络逻辑。
3.2 全局用户信息管理器
存储用户登录状态、用户ID、昵称、权限信息,全局快速判断登录态,统一处理登录、退出登录逻辑。
3.3 App全局配置管理器
管理环境切换(开发/测试/生产)、主题配色、全局开关、埋点配置、动态域名等。
3.4 本地缓存/文件管理器
统一封装沙盒读写、缓存清理、图片缓存、数据持久化逻辑,规范本地存储操作。
3.5 第三方SDK统一管理器
推送、支付、分享、崩溃监控、统计SDK统一初始化,集中管理SDK生命周期。
3.6 全局事件状态管理器
监听登录注销、暗黑模式、语言切换、版本更新等全局状态,实现跨页面通信。
四、项目实战完整示例代码
4.1 实战一:全局网络请求单例
封装通用GET/POST请求,统一配置基础参数,项目直接复用:
import Foundation
/// 全局网络请求管理器
final class NetworkManager {
// 单例
static let shared = NetworkManager()
private init() {
setupBaseConfig()
}
/// 基础配置
private func setupBaseConfig() {
print("初始化:配置超时、请求头、公共参数")
}
/// 通用GET请求
func getRequest(url: String, completion: @escaping (Data?, Error?) -> Void) {
guard let url = URL(string: url) else { return }
URLSession.shared.dataTask(with: url) { data, _, error in
completion(data, error)
}.resume()
}
}
// 业务层调用
NetworkManager.shared.getRequest(url: "https://www.baidu.com") { data, error in
if let data = data {
print("请求成功:\(data)")
}
}
4.2 实战二:全局用户信息单例
管控用户登录态,任意页面快速获取用户信息:
import Foundation
/// 全局用户信息管理器
final class UserManager {
static let shared = UserManager()
private init() {}
/// 用户信息
var userId: String = ""
var nickName: String = ""
var isLogin: Bool = false
/// 登录
func login(userId: String, nickName: String) {
self.userId = userId
self.nickName = nickName
self.isLogin = true
}
/// 退出登录
func logout() {
userId = ""
nickName = ""
isLogin = false
}
}
// 使用示例
UserManager.shared.login(userId: "10001", nickName: "iOS开发工程师")
if UserManager.shared.isLogin {
print("当前登录用户:\(UserManager.shared.nickName)")
}
UserManager.shared.logout()
五、单例模式优缺点总结
5.1 优点
-
节省内存:全局仅创建一次实例,避免重复开辟内存空间;
-
统一管理:集中管控通用逻辑,代码规范性更强;
-
调用简单:无需初始化,全局任意位置直接调用;
-
线程安全:Swift静态常量天然线程安全,无需额外加锁。
5.2 缺点
-
常驻内存:生命周期跟随App,不会主动释放,长期占用内存;
-
耦合度高:过度依赖单例会造成代码耦合严重,不利于模块解耦;
-
测试困难:全局强依赖,不方便做单元测试。
六、开发规范与避坑指南(重点⚠️)
-
严格控制使用范围:仅用于管理器类(网络、用户、SDK),普通业务页面、临时业务类禁止使用;
-
必须私有化构造器:强制添加
private init\(\),防止外部随意创建实例; -
禁止单例嵌套引用:避免多个单例互相持有,造成内存泄漏;
-
轻量化设计:单例内部不要编写复杂冗余业务逻辑,保持工具纯净性;
-
禁止滥用全局变量:不要在单例中随意定义大量全局属性,防止内存膨胀。
七、总结
单例模式是iOS开发最简单、最高频的设计模式,static let shared + private init() 是Swift项目企业级标准写法。开发中要明确使用场景,只用于全局通用管理类,切忌滥用;合理使用单例可以简化代码、统一管控逻辑,滥用则会造成代码耦合、内存常驻问题。
本文所有代码均可直接复制到项目中使用,适合新手入门、面试复习、生产项目开发。
更多推荐

所有评论(0)