【问题标题】:Using arrayController results in "Cannot perform operation without a managed object context"使用 arrayController 会导致“没有托管对象上下文无法执行操作”
【发布时间】:2016-05-03 06:35:09
【问题描述】:

我正在用 Swift 2.2 重写我以前的 objC 应用程序。这是我使用NSArrayController 填充NSTableView 内容的可可应用程序。 错误很明显,尽管在 Objective C 应用程序中也可以使用类似的设置。

这是我的 AppDelegate:

 var coreStack:AP_CoreDataStack!
var mainContext:NSManagedObjectContext!

override func awakeFromNib() {
coreStack = AP_CoreDataStack(){ (result) -> () in
        if result {
            self.mainContext = self.coreStack.mainContext
        }
    }
}

核心数据栈的设置

// MARK: - AP_CoreDataStack Class
class AP_CoreDataStack {

let mainContext: NSManagedObjectContext
let mastercontext: NSManagedObjectContext
var workerContext: NSManagedObjectContext?


internal typealias CallBack = (result:Bool) -> Void
init ( callback: CallBack) { 


    let modelURL = NSBundle.mainBundle().URLForResource("appNameSWIFT", withExtension: "momd")
    if (modelURL == nil) {
        print("Failed to initialize modelURL: \(modelURL)")
    }

    let mom = NSManagedObjectModel(contentsOfURL: modelURL!)
    if mom == nil {
        print("Failed to initialize model")
    }

    let psc = NSPersistentStoreCoordinator(managedObjectModel: mom!)

    mastercontext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
    mastercontext.persistentStoreCoordinator = psc

    mainContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
    mainContext.parentContext = mastercontext


    // add store to psc in background thread
    let qualityOfServiceClass = QOS_CLASS_BACKGROUND
    let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
    dispatch_async(backgroundQueue, {
        //BACKGROUND THREAD
        // adding store to persistent store coordinator
        let options = [NSInferMappingModelAutomaticallyOption:true,
            NSMigratePersistentStoresAutomaticallyOption:true]
        do {
            // store = try psc.addP
            try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: applicationDocumentDirectory(), options: options)
        } catch let error as NSError {
            print("Error: Failed to load store \(error.localizedDescription), \(error.userInfo)")
        }

        // MAIN THREAD
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            // On Main thread pass message that stack setup is complete
            callback(result: true)
        })
    })


}

上面是我的 Obj C 代码的 Swift 版本,它运行良好。我在 xib 文件中有一个 NSArrayController,它绑定到 IB 中的 EntityNSManagedObjectContext

// Bind To Delegate
self.mainContext

似乎 Array 控制器在初始化之前正在访问 mainContext,但这与在 objC 中工作的设置相同,所以为什么它会在 Swift 中导致错误。

编辑:我正在使用常规的 xib 文件。

编辑 2:

显然 mainContext 不为零,因为在这里调用它可以正常工作

    func applicationDidFinishLaunching(aNotification: NSNotification) {
    // Insert code here to initialize your application

    let request = NSFetchRequest(entityName: "AP_EntityA")
    let list:Array<AnyObject>
    do {
        list = try coreStack.mainContext.executeFetchRequest(request)
        for item in list {
            let product = item as! AP_EntityA
           print("item name is: \(product.uniqueName)")
        }
    } catch let error as NSError {
        // failure
        print("Fetch failed: \(error.localizedDescription)")
    }

}

【问题讨论】:

  • nib/storyboard 控制器是什么时候和现在实例化的?
  • @Wain,我正在使用常规的 xib 文件,您可以在其中获得 NSWindow。它在应用加载时被实例化。我没有创建任何额外的视图控制器对象。
  • 您是否复制或重新创建了 XIB?
  • @Willeke,不,我没有。奇怪的是 NSArrayController 即使在 coreDataSetup 完成后也无法识别 mainContext。以编程方式执行 self.arrayController.prepareContent() 会导致相同的错误。不过,我可以通过在同一上下文中执行请求来获取数据。

标签: swift cocoa core-data nsarraycontroller


【解决方案1】:

添加 dynamic 关键字以使 Swift 属性与 KVO 兼容。

dynamic var mainContext:NSManagedObjectContext!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多