RestKit postObject方法中的post对象和它返回的RKMappingResult之间有什么关系?

我一直在浏览RestKit的文档,但是我还没有能够解决RKMappingResult一些细节问题。

我有创buildNSManagedObject ,称为newUser ,并插入mainQueueManagedObjectContext的mainQueueManagedObjectContext的代码。 然后使用我的对象pipe理器的postObject:path:parameters:success:failure:方法将用户发布到服务器。 这似乎工作正常。

当发布请求完成时,我需要更新newUser托pipe对象上的一些字段,这些字段不会根据发布请求的结果进行映射。 传递到块中的mappingResult参数似乎具有与从服务器的响应中设置的所有字段正确映射的托pipe对象。

显然, mappingResult中的对象与我发布的对象不是同一个对象,因为它们不在同一个线程中。 如果我在发布之前保存新newUser ,请求完成后它们的objectID是否相同,并返回映射结果?

我在想象,新newUser和映射结果中的对象都指向存储在CoreData中的同一个对象,是正确的吗? 我问的原因是,这似乎并非如此。 如果我发出一个发布请求并同时保存新的newUser对象和映射结果中返回的对象,我最终在Core Data中有两个不同的对象,一个用于newUser ,一个用于映射结果。 我通过更改newUser对象和newUser对象上的字段,并确认它们都是独立更改来确认这一点。 此外,我下次获取时,获取两个用户对象。 我如何防止这种情况?

如果这是正确的,如果我崩溃会发生什么,请求还没有完成? CoreData中不会有一个存根对象吗?

如果请求失败,如何删除我创build的存根对象? 我可以在失败区域做类似以下的事情吗?

  dispatch_async(dispatch_get_main_queue(), ^{ [newUser.managedObjectContext deleteObject:newRegisteredUser]; }); 

新用户在哪里,是我在mainQueue上创build的托pipe对象。

最后,如果我通过映射结果在后台线程中取回托pipe对象,则无法将返回的用户设置为UI用于从主线程获取信息的用户,那么如何通知用户界面改变它的用户? 我应该发布一个通知,告诉用户界面从Core Data重新获取活动用户吗?

更新关于重复的对象

我做了一些进一步的testing,我肯定会得到一个重复的对象,当职位返回。

我首先创build一个新的newUser并设置属性:

 HNGRRegisteredUser *newUser = [NSEntityDescription insertNewObjectForEntityForName:@"RegisteredUser" inManagedObjectContext:context]; newUser.firstName = @"John" newUser.lastName = @"Smith" newUser.gender = @"Male" newUser.email = @"js@email.com" newUser.hungrosityModel = //fill in all of the attributes for a hungrosityModel, except uniqueID 

在这一点上,newUser.uniqueID == nil。 然后,我保存newUser(我假设我必须这样做RestKit可以使用永久objectID),使一个存根对象。

 NSError *saveError; [newRegisteredUser.managedObjectContext saveToPersistentStore:&saveError]; if (saveError) NSLog(@"Save Error: %@", saveError); NSLog(@"newUser objectID: %@", [newRegisteredUser.objectID URIRepresentation]); 

然后我张贴新的newUser对象。

 [[RKObjectManager sharedManager] postObject:newRegisteredUser path:@"users/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { NSError *saveError; HNGRRegisteredUser *returnedUser = [mappingResult firstObject]; NSLog(@"mappingResult objectID: %@", [returnedUser.objectID URIRepresentation]); [returnedUser.managedObjectContext saveToPersistentStore:&saveError]; if (saveError) NSLog(@"Error saving user upon registration: %@", saveError); } failure:^(RKObjectRequestOperation *operation, NSError *error) { [newUser.managedObjectContext deleteObject:newUser]; }]; 

objectID的打印输出如下。

 newUser objectID: x-coredata://B74AB613-1060-4D98-ABFC-3B4D89AB12C3/RegisteredUser/p2 mappingResult objectID: x-coredata://B74AB613-1060-4D98-ABFC-3B4D89AB12C3/RegisteredUser/p3 

发送给服务器的JSON是:

 { "gender":"Male", "lastName":"Smith", "firstName":"John", "email":"js@email.com", "hungrosityModel": { "totalNumberOfUpdates":0, "peakHungrosity":0.8, "hungrosityFractionAtLastUpdate":0, "rateOfHungrosification":5e-05, "troughHungrosity":0.1, "peakUpdates":0 } } 

从服务器返回的JSON是:

 {"results": [ {"receivedFriendRequests": [], "firstName": "John", "middleName": null, "hungrosityModel": {"uniqueID": 13}, "email": "js@email.com", "gender": "Male", "lastName": "Smith", "sentFriendRequests": [], "uniqueID": 14, "updatedAt": "2014-03-12T17:45:01.973Z", "friends": [], "profileImageUpdatedAt": null, "createdAt": "2014-03-12T17:45:01.809Z"} ]} 

对象的响应和请求描述符是:

 [[RKObjectManager sharedManager].router.routeSet addRoute:[RKRoute routeWithClass:[HNGRRegisteredUser class] pathPattern:@"users/" method:RKRequestMethodPOST]]; RKResponseDescriptor *registrationResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[HNGRRKMappingProvider registeredUserMapping] method:RKRequestMethodPOST pathPattern:@"users/" keyPath:@"results" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; [[RKObjectManager sharedManager] addResponseDescriptor: registrationResponseDescriptor]; RKRequestDescriptor *registrationRequestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[[HNGRRKMappingProvider registeredUserMapping] inverseMapping] objectClass:[HNGRRegisteredUser class] rootKeyPath:nil method:RKRequestMethodPOST]; [[RKObjectManager sharedManager] addRequestDescriptor:registrationRequestDescriptor]; 

用户的映射是:

 RKEntityMapping *_mapping = nil; _mapping = [RKEntityMapping mappingForEntityForName:@"RegisteredUser" inManagedObjectStore:[RKManagedObjectStore defaultStore]]; [_mapping addAttributeMappingsFromArray:@[@"uniqueID", @"createdAt", @"updatedAt", @"firstName", @"middleName", @"lastName", @"email", @"gender", @"profileImageUpdatedAt"]]; [_mapping addRelationshipMappingWithSourceKeyPath:@"hungrosityModel" mapping:[HNGRRKMappingProvider basicModelMapping]]; _mapping.identificationAttributes = @[@"uniqueID"]; 

这是相关的对象映射跟踪:

 D restkit.object_mapping:RKMapperOperation.m:377 Executing mapping operation for representation: { results = ( { createdAt = "2014-03-12T18:22:35.688Z"; dateOfBirth = "2014-03-12T18:24:02Z"; firstName = John; friends = ( ); gender = Male; hungrosityModel = { uniqueID = 14; }; lastName = Smith; middleName = "<null>"; profileImageUpdatedAt = "<null>"; receivedFriendRequests = ( ); sentFriendRequests = ( ); uniqueID = 14; updatedAt = "2014-03-12T18:22:35.856Z"; } ); } and targetObject: <HNGRRegisteredUser: 0xaa8c180> (entity: RegisteredUser; id: 0xa894550 <x-coredata://44B8DF7A-BDC9-45F2-A137-BFAACF4AAF88/RegisteredUser/p2> ; data: { createdAt = nil; dateOfBirth = "2014-03-12 18:24:02 +0000"; email = "js@email.com"; firstName = John; friendRequests = "<relationship fault: 0xa899dd0 'friendRequests'>"; friends = "<relationship fault: 0xa891ea0 'friends'>"; gender = Male; hungrosityModel = "0xa861980 <x-coredata://44B8DF7A-BDC9-45F2-A137-BFAACF4AAF88/BasicModel/p2>"; hungrosityUpdateEvents = "<relationship fault: 0xa829d90 'hungrosityUpdateEvents'>"; isLocalUser = 0; lastName = Smith; middleName = nil; myInvitations = nil; profileImageData = nil; profileImageThumbnailData = nil; profileImageUpdatedAt = nil; receivedInvitations = nil; registeredUserSettings = nil; savedHungrosityComments = "<relationship fault: 0xa8bc450 'savedHungrosityComments'>"; uniqueID = nil; updatedAt = nil; user = nil; userSettings = nil; }) T restkit.object_mapping:RKMapperOperation.m:320 Examining keyPath 'results' for mappable content... D restkit.object_mapping:RKMapperOperation.m:297 Found mappable collection at keyPath 'results': ( { createdAt = "2014-03-12T18:22:35.688Z"; dateOfBirth = "2014-03-12T18:24:02Z"; firstName = John; friends = ( ); gender = Male; hungrosityModel = { uniqueID = 14; }; lastName = Smith; middleName = "<null>"; profileImageUpdatedAt = "<null>"; receivedFriendRequests = ( ); sentFriendRequests = ( ); uniqueID = 14; updatedAt = "2014-03-12T18:22:35.856Z"; } ) D restkit.object_mapping:RKMappingOperation.m:952 Starting mapping operation... T restkit.object_mapping:RKMappingOperation.m:953 Performing mapping operation: <RKMappingOperation 0xa8e4440> for 'HNGRRegisteredUser' object. Mapping values from object { createdAt = "2014-03-12T18:22:35.688Z"; dateOfBirth = "2014-03-12T18:24:02Z"; firstName = John; friends = ( ); gender = Male; hungrosityModel = { uniqueID = 14; }; lastName = Smith; middleName = "<null>"; profileImageUpdatedAt = "<null>"; receivedFriendRequests = ( ); sentFriendRequests = ( ); uniqueID = 14; updatedAt = "2014-03-12T18:22:35.856Z"; } to object <HNGRRegisteredUser: 0xa8833b0> (entity: RegisteredUser; id: 0xa8777e0 <x-coredata:///RegisteredUser/t1FD3D8DE-75AD-4194-B157-EB6931B74BDB6> ; data: { createdAt = nil; dateOfBirth = nil; email = nil; firstName = nil; friendRequests = ( ); friends = ( ); gender = nil; hungrosityModel = nil; hungrosityUpdateEvents = ( ); isLocalUser = 0; lastName = nil; middleName = nil; myInvitations = nil; profileImageData = nil; profileImageThumbnailData = nil; profileImageUpdatedAt = nil; receivedInvitations = nil; registeredUserSettings = nil; savedHungrosityComments = ( ); uniqueID = 14; updatedAt = nil; user = nil; userSettings = nil; }) with object mapping (null) 

让我知道是否有任何更多的信息将有助于知道。

是的,对象id将始终匹配(即使托pipe对象实例不同,它仍然代表相同的底层实体实例)。 当你在主线程上启动的时候,它们通常是相同的托pipe对象实例,RestKit也会在主线程上callback你。

您描述的新实例不会发生。 您发布的原始对象应该直接更新。 在你的情况下,因为服务器正在返回一个对象数组没有发生。 这导致RestKit忽略提供的目标对象并创build新的。 在这种情况下,这是一个新的对象,因为该数组包含一个项目。 要解决这个问题,你将需要修改来自服务器的JSON,因为你不能作为映射的一部分索引到数组中。

要删除,你不需要切换线程(尽pipe你可以如果你想要将来打样),这是正确的做法。

您可以发布通知。 我通常使用一个提取的结果控制器,因为它可以为你pipe理观察的变化。