当我尝试通过几个函数传递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({$0.valueForKey("success") as! Bool == false })
print("INCOMPLETE COUNT: \(incomplete.count)")
let complete = results.filter({$0.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"成功"有价值"真"
由于某些奇怪的原因,我无法在代码编辑器中访问returnItem - 只有当我完全删除syncLocal中的任何代码时才会显示
func syncLocal(item:NSManagedObject,completionHandler:(NSManagedObject!,SyncResponse)->Void) {
completionHandler(item,.Success)
}
如果我这样做,我可以在for循环中的返回块中访问.syntax属性。
奇怪的是,如果我重新粘贴这些东西,在syncLocal中,完成块保持正常运行,应用程序编译并将正确执行。
这是一种奇怪的XCode7 Bug吗?预期的NSManagedObject行为?
第1行是用
中剥离的第2行粘贴的休息回写的答案 0 :(得分:1)
Core Data托管对象上下文中存在线程限制。这意味着您只能在同一个线程中使用特定的托管对象及其上下文。
在您的代码中,您似乎正在使用控制器范围的变量,例如item
。我假设item
是NSManagedObject
或其子类,并且它的上下文只是您在应用中使用的一个上下文。 FRC上下文必须是主线程上下文(并发类型为NSManagedObjectContext
的{{1}})。
显然,服务器请求的回调将在后台线程上。因此,您无法使用托管对象。
你有两个解决方案。您可以创建子上下文,执行需要执行的更新,保存,然后保存主上下文。这需要更多参与,你可以在那里寻找大量的例子和教程来开始。这是标准且最强大的解决方案。
或者,在后台回调中,您只需确保主线程上发生上下文更新。
NSMainThreadConcurrencyType