我在使用 StackMob 作为我的 iOS 应用程序的后端时遇到了一个问题(尽管我不确定这是错误使用 StackMob 的方法还是 iOS 问题)。
我允许用户创建一个只是子类 NSManagedObject 的 post 对象,并将其上传到服务器以在应用程序的其他部分中使用。方法中出现的问题:
[NSManagedObjectContext saveOnSuccess:<^(void)successBlock> onFailure:<^(NSError *error)failureBlock>];
在这里,我使用 StackMob 方法异步保存在NSManagedObjectContext(Concurrency) 类别参考中找到的 MOC 。
此视图之前的视图对最近的帖子执行提取,并且在未执行提取的情况下发布工作正常,但如果执行提取,则在保存 MOC 以上传新帖子时,我收到以下输出错误信息:
2013-09-11 17:08:09.284 imageTagging[1824:1843] -[__NSDictionaryI bytes]: unrecognized
selector sent to instance 0x1e3123d0
2013-09-11 17:08:09.291 imageTagging[1824:1843] *** Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI bytes]: unrecognized
selector sent to instance 0x1e3123d0'
*** First throw call stack:
(0x318cb3e7 0x395c6963 0x318cef31 0x318cd64d 0x31825208 0x321631cf 0x3216b991 0x15ea99
0x318c8757 0x15e109 0x15dabf 0x10d1c3 0x318d05b7 0x10cd4d 0x10c829 0x10923b 0x1076d9
0x3166c431 0x316c44d1 0x1685c3 0x316c7e5d 0x399e3b3b 0x399e167d 0x399e4613 0x399e47d9
0x39a087f1 0x39a08684)
libc++abi.dylib: terminate called throwing an exception
(lldb)
数据仍在上传到 StackMob 服务器,并且可以在稍后运行应用程序时调用——但应用程序在尝试保存它时会崩溃。所有这些都在视图控制器中执行。我试图强制在主线程上执行所有 MOC 保存,但错误仍然存在。我还尝试在保存完成后分派“保存队列”并更新 UI。这种方法似乎有点作用,但随后又出现了错误(可能只是侥幸)。我还尝试使用文档中的同步保存调用来做到这一点
尝试执行其他保存时也会发生相同的错误(例如在创建新用户或更新用户信息时),并且所有这些都归结为导致问题的相同函数调用。还可能值得注意的是错误总是相同的(特别是类型__NSDictionaryI
试图访问其无法识别的选择器bytes
。
这是填写了输入参数的完整方法调用:
//save context
[[[[SMClient defaultClient] coreDataStore] contextForCurrentThread] saveOnSuccess:^{
NSLog(@"You created a new Post object!");
[[[[SMClient defaultClient] coreDataStore] contextForCurrentThread] refreshObject:newPost mergeChanges:YES];
NSLog(@"refreshed");
} onFailure:^(NSError *error) {
NSLog(@"There was an error! %@", error);
}];
更新:我已将问题缩小到对前一个视图控制器执行的获取返回的信息处理不当。具体来说,它发生在尝试使用数据进行更新时获取结果之后。
由于这种新见解,我真正面临的问题是如何在获取后在上下文中正确保存托管对象。我相信 StackMob 负责在获取(即服务器查询)之后创建托管对象。我尝试从结果数组中创建一个新对象(每个“obj”都是一个 NSManagedObject):
[results enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSManagedObject *newObj = obj;
}];
我还尝试通过对象 ID(每个“obj”是一个 objectID)引用获取的结果:
[results enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSManagedObject *newObj = [self.managedObjectContext objectWithID:obj];
}];
任何有关如何正确执行此操作的见解将不胜感激!
更新 2:看起来错误实际上是在尝试使用和保存地理位置数据时发生的。为了使用查询对象的地理位置数据,必须取消存档——但要保存它,必须存档。我现在正在研究如何做到这一点,如果我遇到一个好的解决方案,我会再次更新。
最后更新:明白了!事实证明,我遇到的问题是我正在取消归档地理定位数据以更新 UI 并进行一些计算,当我再次归档它以正确存储时,我在引用未归档数据的地图上创建了一个注释. 因此,MOC 维护了无法通过 StackMob 方法保存的数据。通过仅保存存档数据,我可以根据需要随时保存,并在需要使用地理数据时取消存档。问题解决了!
如果有人遇到类似问题并需要一些见解或参考,请随时发表评论!