我正在尝试通过推送到主线程中完成的后台Core Data / RestKit操作来加速应用程序。 以下简单映射操作在RestKit代码中崩溃:
RKObjectManager *manager = [RKObjectManager sharedManager];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"keyPath IN %@", objectType];
RKEntityMapping *mapping = (RKEntityMapping *)[[[manager responseDescriptors] filteredArrayUsingPredicate:pre].firstObject mapping];
NSDictionary *mappingsDictionary = @{ [NSNull null]: mapping };
RKManagedObjectStore *store = [RKManagedObjectStore defaultStore];
RKManagedObjectMappingOperationDataSource *mappingDataSource = [[RKManagedObjectMappingOperationDataSource alloc] initWithManagedObjectContext:store.mainQueueManagedObjectContext cache:store.managedObjectCache];
RKMapperOperation *mapperOperation = [[RKMapperOperation alloc] initWithRepresentation:data mappingsDictionary:mappingsDictionary];
mapperOperation.mappingOperationDataSource = mappingDataSource;
[manager.operationQueue addOperation:mapperOperation];
如果我在主线程中执行操作:
[mapperOperation execute:&mappingError];
一切正常。
我应该添加崩溃只发生在映射涉及关系时。我的意思是当我获得的JSON包含子对象时它只会崩溃。
知道我做错了吗?
更新:更多详情。
范围内的模型:
Users
和Photos
。 Users
“有很多”Photos
。
映射:
RKEntityMapping *entityMappingUser = [RKEntityMapping mappingForEntityForName:@"User" inManagedObjectStore:managedObjectStore];
[entityMappingUser addAttributeMappingsFromDictionary:@{
@"id": @"userID",
@"name": @"name",
@"surname": @"surname",
}];
entityMappingUser.identificationAttributes = @[ @"userID" ];
RKEntityMapping *entityMappingPhoto = [RKEntityMapping mappingForEntityForName:@"Photo" inManagedObjectStore:managedObjectStore];
[entityMappingPhoto addAttributeMappingsFromDictionary:@{
@"id": @"photoID",
@"uri": @"uri",
}];
entityMappingPhoto.identificationAttributes = @[ @"photoID" ];
[entityMappingUser addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"photos" toKeyPath:@"photos" withMapping:entityMappingPhoto]];
JSON:
"users":{"245659":{"name":"john","surname":"smith", "id":245659, "photos":[{"id":28945,"uri":"http://..."}]}}
这是我正在做的事情:
我在各个地方随机崩溃。例如,我有时会在RKMappingOperation中获得一个,l.575(v20.3):
if (attributeMapping.destinationKeyPath) {
[self.destinationObject setValue:value forKeyPath:attributeMapping.destinationKeyPath]; #EXC_BAD_ACCESS
}
然而,destinationObject看起来“很好”
<TMUser: 0xb54ad20> (entity: User; id: 0xb545900 <x-coredata:///User/tA94DE417-D68E-4D94-927F-6E2667A3BCFD464> ; data: {
surname = "smith";
name =nil;
photos = (
);
})
以及值(“john”)和destinationKeyPath(名称)。
答案 0 :(得分:1)
您不应该在与创建托管对象上下文的线程不同的后台线程上执行这些操作。这将导致CoreData存储不稳定,并导致应用程序崩溃。您必须非常小心使用线程访问对象的方式。例如,访问从不属于当前线程的上下文检索的对象将导致崩溃。
请务必阅读Apple提供的Concurrency with CoreData
文档:
https://developer.apple.com/library/ios/documentation/cocoa/conceptual/CoreData/Articles/cdConcurrency.html