- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我一直在查看关于 RestKit 的文档,但我一直无法弄清楚 RKMappingResult
的一些细节。
我有创建 NSManagedObject
的代码,称为 newUser
,并插入到 RestKit RKManagedObjectStore 的 mainQueueManagedObjectContext
中。然后,我使用对象管理器的 postObject:path:parameters:success:failure:
方法将用户发布到服务器。这似乎工作正常。
我需要在 post 请求完成时更新 newUser
托管对象上的一些字段,这些字段不会从 post 请求的结果中映射。传递到 block 中的 mappingResult
参数似乎具有与服务器响应中设置的所有字段正确映射的托管对象。
显然,mappingResult
中的对象与我发布的对象不同,因为它们不在同一个线程中。如果我在发布之前保存 newUser
,当请求完成并返回映射结果时,它们的 objectID
是否相同?
我在想象 newUser
和映射结果中的对象指的是存储在 CoreData 中的同一个对象,对吗?我问的原因是,情况似乎并非如此。如果我发出一个发布请求并保存 newUser
对象和 mappingResult
中返回的对象,我最终会在 Core Data 中得到两个不同的对象,一个用于 >newUser
和一个用于映射结果。我通过更改 mappingResult 对象和 newUser
对象上的一个字段并看到它们都是独立更改的来确认这一点。此外,在我下次获取时获取两个用户对象。我该如何防止这种情况?
但是,如果这是正确的,那么如果我崩溃了请求还没有完成会怎样?我不会有一个 stub 对象只是卡在 CoreData 中吗?
如果请求失败,如何删除我创建的 stub 对象?我可以在失败 block 中执行类似以下的操作吗?
dispatch_async(dispatch_get_main_queue(), ^{
[newUser.managedObjectContext deleteObject:newRegisteredUser];
});
newUser
是我在 mainQueue 上创建的托管对象。
最后,如果我通过映射结果在后台线程中取回托管对象,我无法将 returnedUser 设置为 UI 用来从中获取信息的用户,因为它在主线程上,所以如何通知用户界面更改它的用户?我应该发布一条通知,告诉 UI 从 Core Data 重新获取事件用户吗?
关于重复对象的更新
我做了一些进一步的测试,当帖子返回时我肯定得到了一个重复的对象。
我首先创建一个 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),以创建一个 stub 对象。
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 将始终匹配(即使托管对象实例不同,它仍然表示相同的底层实体实例)。它们通常是您在主线程上启动时相同的托管对象实例,RestKit 也会在主线程上调用您。
您描述的新实例不会发生。您发布的原始对象应该直接更新。在您的情况下,这不会发生,因为服务器正在返回一个对象数组。这导致 RestKit 忽略提供的目标对象并创建新的目标对象。在本例中,这是一个新对象,因为数组包含一项。要解决此问题,您需要修改来自服务器的 JSON,因为您无法将数组作为映射的一部分进行索引...
要删除,您不需要切换线程(但如果您希望将来进行验证,您可以切换线程),这是正确的方法。
您可以发布通知。我通常使用 fetched results controller,因为它会为您管理观察变化。
关于ios - RestKit postObject 方法中的 post 对象和它返回的 RKMappingResult 是什么关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22343101/
我的一位教授给了我们一些考试练习题,其中一个问题类似于下面(伪代码): a.setColor(blue); b.setColor(red); a = b; b.setColor(purple); b
我似乎经常使用这个测试 if( object && object !== "null" && object !== "undefined" ){ doSomething(); } 在对象上,我
C# Object/object 是值类型还是引用类型? 我检查过它们可以保留引用,但是这个引用不能用于更改对象。 using System; class MyClass { public s
我在通过 AJAX 发送 json 时遇到问题。 var data = [{"name": "Will", "surname": "Smith", "age": "40"},{"name": "Wil
当我尝试访问我的 View 中的对象 {{result}} 时(我从 Express js 服务器发送该对象),它只显示 [object][object]有谁知道如何获取 JSON 格式的值吗? 这是
我有不同类型的数据(可能是字符串、整数......)。这是一个简单的例子: public static void main(String[] args) { before("one"); }
嗨,我是 json 和 javascript 的新手。 我在这个网站找到了使用json数据作为表格的方法。 我很好奇为什么当我尝试使用 json 数据作为表时,我得到 [Object,Object]
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我听别人说 null == object 比 object == null check 例如: void m1(Object obj ) { if(null == obj) // Is thi
Match 对象 提供了对正则表达式匹配的只读属性的访问。 说明 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的
Class 对象 使用 Class 语句创建的对象。提供了对类的各种事件的访问。 说明 不允许显式地将一个变量声明为 Class 类型。在 VBScript 的上下文中,“类对象”一词指的是用
Folder 对象 提供对文件夹所有属性的访问。 说明 以下代码举例说明如何获得 Folder 对象并查看它的属性: Function ShowDateCreated(f
File 对象 提供对文件的所有属性的访问。 说明 以下代码举例说明如何获得一个 File 对象并查看它的属性: Function ShowDateCreated(fil
Drive 对象 提供对磁盘驱动器或网络共享的属性的访问。 说明 以下代码举例说明如何使用 Drive 对象访问驱动器的属性: Function ShowFreeSpac
FileSystemObject 对象 提供对计算机文件系统的访问。 说明 以下代码举例说明如何使用 FileSystemObject 对象返回一个 TextStream 对象,此对象可以被读
我是 javascript OOP 的新手,我认为这是一个相对基本的问题,但我无法通过搜索网络找到任何帮助。我是否遗漏了什么,或者我只是以错误的方式解决了这个问题? 这是我的示例代码: functio
我可以很容易地创造出很多不同的对象。例如像这样: var myObject = { myFunction: function () { return ""; } };
function Person(fname, lname) { this.fname = fname, this.lname = lname, this.getName = function()
任何人都可以向我解释为什么下面的代码给出 (object, Object) 吗? (console.log(dope) 给出了它应该的内容,但在 JSON.stringify 和 JSON.parse
我正在尝试完成散点图 exercise来自免费代码营。然而,我现在只自己学习了 d3 几个小时,在遵循 lynda.com 的教程后,我一直在尝试确定如何在工具提示中显示特定数据。 This code
我是一名优秀的程序员,十分优秀!