我正在关注Big Nerd Ranch的iOS编程书中的UITableView教程。在本教程中,我们将一个新属性分配给UIViewController,如下所示:
class ItemsViewController: UITableViewController {
var itemStore: ItemStore!
}
但是,在应用程序的AppDelegate中,我们在AppDelegate中实例化了这个itemStore属性,如下所示:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let itemStore = ItemStore()
let itemsController = window?.rootViewController as! ItemsViewController
itemsController.itemStore = itemStore
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
我的问题是,为什么app委托为其他viewControllers中使用的属性创建实例?不应该在实际使用它的viewController中实例化此属性,或者通过这样做,itemStore对象在应用程序的持续时间内保持活动状态?
答案 0 :(得分:1)
这样做是为了让ItemsViewController
更具可重用性。 ItemsViewController
不需要知道ItemStore
对象的详细信息,包括要实例化的ItemStore
子类。它只需要知道该对象所遵循的接口。通过在外部设置ItemStore
,ItemsViewController
可以轻松地与ItemStore
的其他子类一起使用,而无需进行更改。
第10章,给予控制器访问商店一节 iOS编程:The Big Nerd Ranch Guide,第6版中介绍了这一点。< / p>
答案 1 :(得分:0)
在ItemsViewController
班级中,itemStore
定义为
var itemStore: ItemStore!
这里itemStore
是一个未包装的变量。
所以它不接受nil
值。否则会导致运行时崩溃。意外nil
。
这就是为什么在AppDelegate
我们需要确保itemStore
对象不是nil
let itemStore = ItemStore()
let itemsController = window?.rootViewController as! ItemsViewController
itemsController.itemStore = itemStore
答案 2 :(得分:0)
这样声明itemStore
并不意味着它将保持应用程序生命,它是didFinishLaunchingWithOptions
内的局部变量,如果可以在{{1}内初始化这种类外的初始化风格是没用的这可能是因为数据逻辑在Appdelegate中总是与coredata一起发生,或者它的项目将从ItemsViewController
答案 3 :(得分:0)
这是否是Big Nerd Ranch的意图,将ItemStore
实例传递给视图控制器的最佳理由是可测试性。这种模式称为依赖注入。
我们的想法是,您可以在单元测试期间向视图控制器提供模拟的ItemStore
。 (这假设你进行单元测试,你应该!:)
使用模拟,您可以模拟视图控制器在ItemStore
为空,空或包含某些项目时的行为方式。