在 iOS 中正确访问 ViewController 中的核心数据上下文 [重复]
Posted
技术标签:
【中文标题】在 iOS 中正确访问 ViewController 中的核心数据上下文 [重复]【英文标题】:accessing Core Data context in ViewController properly in iOS [duplicate] 【发布时间】:2016-08-30 19:18:03 【问题描述】:我一直在做
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
只在我的 ViewControllers 中使用上下文,但在我阅读的 Apples ios 开发人员库中
“视图控制器通常不应该从全局对象(例如应用程序委托)中检索上下文”
那么从 AppDelegate 访问上下文的正确方法是什么,我有点困惑...
【问题讨论】:
@Wain 重复的问题没有带有代码的示例解决方案。那该怎么办,我应该把我的答案移到那里吗? 你可以,当我将其标记为重复时,你的答案是一个简单的链接,但是这个问题/答案没有意义,因为它是相同的,而且它的理论很重要 - 添加在很多情况下,代码只是让人们不假思索地复制和粘贴 【参考方案1】:您是对的,Apple 不建议 iOS 应用程序采用这种方式。
创建CoreData堆栈是最好的解决方案:
所以在你的 AppDelegate.swift 中:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
var window: UIWindow?
lazy var coreDataStack = CoreDataStack()
func application(_ application: UIApplication,
didFinishLaunchingWithOptions
launchOptions: [NSObject: Any]?) -> Bool
let navigationController =
self.window!.rootViewController as! UINavigationController
let viewController =
navigationController.topViewController as! ViewController
viewController.managedContext = coreDataStack.context
return true
func applicationDidEnterBackground(_ application: UIApplication)
coreDataStack.saveContext()
func applicationWillTerminate(_ application: UIApplication)
coreDataStack.saveContext()
然后,一个 CoreDataStack.swift(负责 MOC 的所有职责的类)的示例:
import CoreData
class CoreDataStack
lazy var context: NSManagedObjectContext =
var managedObjectContext = NSManagedObjectContext(
concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = self.psc
return managedObjectContext
()
fileprivate lazy var psc: NSPersistentStoreCoordinator =
let coordinator = NSPersistentStoreCoordinator(
managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory
.appendingPathComponent(self.modelName)
do
let options =
[NSMigratePersistentStoresAutomaticallyOption : true]
try coordinator.addPersistentStore(
ofType: NSSQLiteStoreType, configurationName: nil, at: url,
options: options)
catch
print("Error adding persistent store.")
return coordinator
()
fileprivate lazy var managedObjectModel: NSManagedObjectModel =
let modelURL = Bundle.main
.url(forResource: self.modelName,
withExtension: "momd")!
return NSManagedObjectModel(contentsOf: modelURL)!
()
fileprivate lazy var applicationDocumentsDirectory: URL =
let urls = FileManager.default.urls(
for: .documentDirectory, in: .userDomainMask)
return urls[urls.count-1]
()
func saveContext ()
if context.hasChanges
do
try context.save()
catch let error as NSError
print("Error: \(error.localizedDescription)")
abort()
最后是 ViewController.swift 的示例:
import CoreData
class ViewController: UIViewController
var managedContext: NSManagedObjectContext!
override func viewDidLoad()
let myEntity = NSEntityDescription.entity(forEntityName: "MyEntityName",
in: managedContext)
...
【讨论】:
等等...所以,我不应该使用 xcode 自动生成的核心数据堆栈吗?这与有何不同 是的,正如引用的“理想情况下,每个视图控制器都应该是一个独立的岛屿。它不应依赖于其父级,也不应依赖于 Application Delegate。一旦视图控制器被推到屏幕上,理想情况下它应该是它自己的主人。他们的文档有点乱。这里有更多信息:cimgf.com/2011/01/07/… 感谢链接和示例代码,非常有帮助 我的回答对你有帮助吗? :) 是的,非常有帮助。谢谢你。但是在更改之后,我决定改回原来的方法。原因是 1. 我没有重用我的代码。 2. 我的项目很简单,以“正确”的方式进行实际上会使事情复杂化一点。以上是关于在 iOS 中正确访问 ViewController 中的核心数据上下文 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何从另一个 UIView 类访问 UIControl 的值