我在使用StackMob作为我的iOS应用程序的后端时遇到了一个问题(虽然我不确定这是否是错误地使用StackMob的方法或iOS问题)。
我允许用户创建一个post对象,它只是一个子类NSManagedObject,并将其上传到服务器以便在应用程序的其他部分中使用。出现的问题出现在方法中:
[NSManagedObjectContext saveOnSuccess:<^(void)successBlock> onFailure:<^(NSError *error)failureBlock>];
在这里,我使用StackMob方法异步保存NSManagedObjectContext(Concurrency) Category Reference中的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。这种方法似乎有点工作,但随后又出现了错误(可能只是一个侥幸)。我还尝试使用synchronous save calls in the documentation
执行此操作尝试执行其他保存时也会发生同样的错误(例如在创建新用户之后或更新用户的信息时),并且所有这些都归结为导致问题的同一函数调用。值得注意的是,错误总是相同的(特别是__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方法保存的数据。通过仅保存存档数据,我可以根据需要随时保存,只需在需要使用时解压缩地理数据。问题解决了!
如果有人遇到类似问题并需要一些见解或参考,请随时发表评论!
答案 0 :(得分:0)
我将把我的最后更新作为答案,因为它解释了我是如何解决这个问题的。
最终更新: 搞清楚了!事实证明,我遇到的问题是我取消了地理位置数据的归档以更新UI并进行一些计算,当我再次存档以便正确存储时,我在地图上创建了一个引用未归档数据的注释。结果,MOC维护了无法通过StackMob方法保存的数据。通过仅保存存档数据,我可以根据需要随时保存,只需在需要使用时解压缩地理数据。问题解决了!
如果有人遇到类似问题并需要一些见解或参考,请随时发表评论!
故事的道德,如果您遇到与此类似的问题,请确保您没有(即使您不是故意)在任何托管中存储对未归档SMGeoPoint
数据的引用对象。它试图存储导致问题的那些。