使用arrayController导致“无法在没有托管对象上下文的情况下执行操作”

时间:2016-05-03 06:35:10

标签: swift cocoa core-data nsarraycontroller

我正在重写我之前在Swift 2.2中使用的objC应用程序。这是cocoa应用程序,我使用NSArrayController来填充NSTableView内容。 虽然类似的设置在Objective C app中有效,但错误很明显。

这是我的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不是nil,因为这里调用它可以正常工作

    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)")
    }

}

1 个答案:

答案 0 :(得分:1)

添加dynamic关键字以使Swift属性符合KVO。

dynamic var mainContext:NSManagedObjectContext!