为何要在AppDelegate中为其他ViewController所用属性创建实例?
嘿,这个问题问得特别到位!这其实是iOS入门阶段很典型的依赖注入实践,同时也和AppDelegate在应用中的核心角色有关,咱们一步步理清楚:
1. AppDelegate是应用的"启动总控"
iOS应用启动时,系统第一个初始化的核心对象就是AppDelegate,它负责处理应用启动、前后台切换等生命周期关键事件。在这个阶段创建ItemStore实例,能确保这个数据层对象从应用启动就存在,不会在ViewController需要它的时候还没准备好——毕竟ItemsViewController的界面加载是在AppDelegate完成启动流程之后才开始的。
2. 不让ViewController"身兼数职"
如果咱们把itemStore = ItemStore()写在ItemsViewController的viewDidLoad里,那这个ViewController就既要管UITableView的界面展示、用户交互,又要负责数据对象的初始化,违反了单一职责原则。把实例创建的工作交给AppDelegate,ViewController只需要专注于"使用itemStore来展示和操作数据"这一件事,代码逻辑会更清晰。
3. 依赖注入让代码更灵活、好测试
这种从外部给ViewController传入依赖对象的方式,就是最基础的依赖注入:
- 后续如果要升级
ItemStore(比如改成支持网络请求的子类),只需要在AppDelegate里修改初始化代码,完全不用动ItemsViewController的逻辑; - 做单元测试的时候,你可以轻松传入一个模拟的
ItemStore(比如预设好测试数据的假对象),不用依赖真实的数据存储,就能单独测试ViewController的界面逻辑。
4. 保证数据状态的一致性
如果你的应用后续扩展出其他页面(比如商品详情页),也需要操作同一个ItemStore里的数据,那在AppDelegate里创建的单实例就能让所有页面共享同一个数据状态,避免出现数据不一致的问题。当然现在有更优雅的方式(比如单例、依赖注入容器),但在入门教程里,用AppDelegate来做这种初始化是最直观易懂的。
结合你的代码来看:ItemsViewController里只声明了var itemStore: ItemStore!(隐式解包可选类型,明确表示这个属性会在ViewController使用前被赋值),而AppDelegate在启动流程中完成实例初始化并传递给ViewController,这样当ViewController加载界面时,itemStore已经完全就绪可以使用了。
内容的提问来源于stack exchange,提问作者Laurence Wingo

