UIPageViewController如何在子控制器间共享唯一tasks数组实例?
你当前将tasks声明为MasterViewController静态属性的方案功能上可行,但架构设计上存在明显缺陷,以下是具体分析和优化建议:
现有方案的合理性
- 静态属性本身属于类级别的全局唯一存储,完全满足你要求的「全局仅一个实例、所有子控制器共享」的需求,读写逻辑直接,不需要额外实现单例,符合你不想用单例的诉求。
- 配合NotificationCenter发送更新通知,只要修改数据后正确触发通知,就能实现所有子控制器的数据同步,功能层面没有问题。
现有方案的问题
- 耦合度过高:所有子控制器都直接依赖
MasterViewController,如果后续你调整页面架构,比如替换容器控制器、拆分页面结构,所有子控制器中访问tasks的代码都需要同步修改,可维护性差。 - 职责不清晰:
MasterViewController的核心职责是管理PageViewController的页面切换逻辑,将全局业务数据存储在视图控制器的静态属性中,违反了单一职责原则,架构分层混乱。 - 无安全保护:当前实现没有做线程安全控制,如果后续有后台线程修改
tasks的场景(比如网络同步数据、后台批量更新任务),直接读写数组很容易出现线程冲突导致崩溃,也没有统一的修改入口,很容易出现修改后漏发通知的问题。
更优的实现方案(无需使用争议性的全局单例)
你可以单独封装一个轻量的 Task 数据管理工具,把数据存储、修改、通知发送的逻辑统一收敛,不需要生成实例,直接使用静态方法和属性即可,同时避免了把数据耦合在视图控制器中:
// 单独的Task数据管理层,和视图层完全解耦 struct TaskStorage { // 私有存储,禁止外部直接修改 private static var _tasks: [Task] = [ Task(id: "1", title: "Mock up onboarding", completed: true, priority: 0), Task(id: "2", title: "Connect to Firebase", completed: false, priority: 1), Task(id: "3", title: "Code review", completed: false, priority: 0), Task(id: "4", title: "Add beta testers to TestFlight", completed: false, priority: 1) ] // 串行队列保证线程安全 private static let safeQueue = DispatchQueue(label: "com.yourApp.taskStorageQueue") // 对外只读的任务列表 static var tasks: [Task] { safeQueue.sync { _tasks } } // 封装新增任务方法,修改后自动发送通知 static func addTask(_ task: Task) { safeQueue.async { _tasks.append(task) // 切回主线程发通知,保证UI更新在主线程执行 DispatchQueue.main.async { NotificationCenter.default.post(name: NSNotification.Name("TasksDidUpdate"), object: nil) } } } // 其他删除、修改任务的方法也按同样逻辑封装即可 }
子控制器使用时直接调用TaskStorage.tasks读取数据,调用TaskStorage.addTask(newTask)新增数据,完全不需要依赖任何视图控制器,后续架构调整也不需要修改数据访问的代码。
如果你不想引入新的类型,也可以选择依赖注入的方式:在MasterViewController初始化子控制器时,将tasks的读写权限通过闭包或者代理的方式传给子控制器,完全消除全局依赖,耦合度更低,更符合iOS开发的最佳实践。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

