传递 NSManagedObject

passing around NSManagedObjects

当我尝试通过多个函数传递 NSManagedObject 时出现奇怪的错误。 (都在同一个VC)。

这里是有问题的两个函数:

func syncLocal(item:NSManagedObject,completionHandler:(NSManagedObject!,SyncResponse)->Void) {

    let savedValues = item.dictionaryWithValuesForKeys([
        "score",
        "progress",
        "player"])

    doUpload(savedParams) { //do a POST request using params with Alamofire
        (success) in

        if success {
            completionHandler(item,.Success)
        } else {
            completionHandler(item,.Failure)
        }        
    }    
}


func getSavedScores() {

    do {
        debugPrint("TRYING TO FETCH LOCAL SCORES")
        try frc.performFetch()

        if let results = frc.sections?[0].objects as? [NSManagedObject] {

            if results.count > 0 {

                print("TOTAL SCORE COUNT: \(results.count)")

                let incomplete = results.filter({[=10=].valueForKey("success") as! Bool == false })
                print("INCOMPLETE COUNT: \(incomplete.count)")

                let complete = results.filter({[=10=].valueForKey("success") as! Bool == true })
                print("COMPLETE COUNT: \(complete.count)")

                if incomplete.count > 0 {

                    for pendingItem in incomplete {

                        self.syncScoring(pendingItem) {
                            (returnItem,response) in

                            let footest = returnItem.valueForKey("player") //only works if stripping syncScoring blank

                            switch response { //response is an enum

                            case .Success:
                                print("SUCCESS")

                            case .Duplicate:
                                print("DUPLICATE")

                            case .Failure:
                                print("FAIL")

                            }
                        }
                    }  //sorry for this pyramid of doom
                }
            }
        }

    } catch {
        print("ERROR FETCHING RESULTS")
    }  
}

我想要达到的目标: 1. 查找本地保存的无法提交到服务器的分数。 2. 如果有未提交的分数,则启动对服务器的POST调用。 3. 如果POST得到200:ok,标记item.key"success",值为"true"

出于某种奇怪的原因,我根本无法在代码编辑器中访问 returnItem - 只有当我完全删除 syncLocal 中的任何代码时,它看起来像

func syncLocal(item:NSManagedObject,completionHandler:(NSManagedObject!,SyncResponse)->Void) {

    completionHandler(item,.Success)

}

如果这样做,我可以在 for 循环中访问返回块中的 .syntax 属性。

奇怪的是,如果我将这些东西粘贴回去,在 syncLocal 中,完成块保持正常运行,应用程序编译并正确执行。

这是某种奇怪的 XCode7 错误吗?预期的 NSManagedObject 行为?

第 1 行被剥离,第 2 行粘贴了 rest call back

Core Data 托管对象上下文中存在线程限制。这意味着您只能在同一个线程中使用特定的托管对象及其上下文。

在您的代码中,您似乎使用了控制器范围的变量,例如 item。我假设 itemNSManagedObject 或其子类,并且它的上下文只是您在应用程序中使用的一个上下文。 FRC上下文必须是主线程上下文(并发类型NSMainThreadConcurrencyTypeNSManagedObjectContext)。

显然,来自服务器请求的回调将在后台线程上进行。所以你不能使用你的托管对象。

你有两个解决方案。您可以创建一个子上下文,执行您需要执行的更新,保存,然后保存主上下文。这有点复杂,您可以从那里寻找大量示例和教程来开始。这是标准且最可靠的解决方案。

或者,在后台回调中,您只需确保上下文更新发生在主线程上。

dispatch_async(dispatch_get_main_queue()) {
   // update your managed objects & save
}