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

2024-04-13

我一直在浏览 RestKit 的文档,但我无法弄清楚有关的一些细节RKMappingResult.

我有创建一个的代码NSManagedObject,称为newUser,并插入到mainQueueManagedObjectContextRestKit RKManagedObjectStore 的。然后我使用我的对象管理器postObject:path:parameters:success:failure:将用户发布到服务器的方法。这看起来效果很好。

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

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

我想象着newUser映射结果中的对象引用存储在 CoreData 中的同一对象,是否正确?我问的原因是,事实似乎并非如此。如果我发出一个帖子请求并保存两个newUser对象和返回的对象mappingResult,我最终在核心数据中得到了两个不同的对象,一个用于newUser一个用于映射结果。我通过更改映射结果对象和newUser反对并发现它们都是独立改变的。此外,下次获取时会获取两个用户对象。我该如何防止这种情况?

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

如果请求失败,如何删除我创建的存根对象?我可以在故障块中执行类似以下操作吗?

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

Where newUser,是我在 mainQueue 上创建的托管对象。

最后,如果我通过映射结果在后台线程中返回托管对象,我无法将 returnedUser 设置为 UI 用来获取信息的用户,因为它位于主线程上,那么我如何通知UI 来更改其用户?我是否应该发布一条通知,告诉 UI 从 Core Data 重新获取活动用户?

关于重复对象的更新

我做了一些进一步的测试,当帖子返回时我肯定会得到一个重复的对象。

我首先创建一个newUser并为其设置属性:

HNGRRegisteredUser *newUser = [NSEntityDescription insertNewObjectForEntityForName:@"RegisteredUser" inManagedObjectContext:context];
newUser.firstName = @"John"
newUser.lastName = @"Smith"
newUser.gender = @"Male"
newUser.email = @"[email protected] /cdn-cgi/l/email-protection"
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 object.

[[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":"[email protected] /cdn-cgi/l/email-protection",
    "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": "[email protected] /cdn-cgi/l/email-protection",
     "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 = "[email protected] /cdn-cgi/l/email-protection";
        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,因为您无法将数组索引作为映射的一部分...

要删除,您不需要切换线程(尽管如果您想要将来校对,您可以切换线程),这是正确的方法。

您可以发布通知。我通常使用获取结果控制器,因为它可以为您管理观察更改。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 如何将CIFilter应用到UIView上?

    根据Apple docs 过滤属性CALayer不支持iOS 当我使用正在申请的应用程序之一时CIFilter to UIView即 Splice Funimate 和 Artisto 的视频编辑器 Videoshow FX 这意味着我们可
  • TTTAttributedLabel 可点击截断标记

    我有一个 TTTAttributedLabel 并为其指定了一个自定义属性截断标记 NSAttributedString atributedTruncationToken NSAttributedString alloc initWithS
  • 如何在Sprite Kit中实现鼠标关节?

    我已经在 iOS 上用 Cocos2d Box2d 编写了拖放功能的工作实现 我需要将它移植到 Sprite Kit 逻辑非常基本 当用户触摸屏幕时 找到手指下的精灵 在找到的精灵和场景的物理体之间创建鼠标关节 将关节的目标设置为触摸位置
  • 如何在 iOS 上固定证书的公钥

    在提高我们正在开发的 iOS 应用程序的安全性时 我们发现需要对服务器的 SSL 证书 全部或部分 进行 PIN 操作以防止中间人攻击 尽管有多种方法可以做到这一点 但当您搜索此内容时 我只找到了固定整个证书的示例 这种做法会带来一个问题
  • 子类 PFObject 上的 PFUser 属性

    我使用以下类 动态属性以及 m 文件中的 load 和 parseClassName 方法 对 PFObject 进行了子类化 interface DAOpponents PFObject
  • 在故事板中将 UITableView 的 rowHeight 设置为 UITableViewAutomaticDimension ?

    在 Xcode 6 中创建 iOS 8 应用程序时 如何设置 UITableViewrowHeight to UITableViewAutomaticDimension In WWDC 2014 第 226 场会议 表和集合视图中的新增功能
  • 如何在 Firebase Analytics 事件中报告参数

    我用过Fabric with iOS在此之前 在同一分析事件中报告自定义参数非常容易 如下所示 Answers logCustomEvent withName saved border customAttributes image inde
  • 从 IOS 应用程序注销的完美方法是什么?

    下面的代码可以工作 但有一个错误 场景是 我首先登录进入应用程序系统 登录成功后 应用程序将设置 UserDefaults UserId 之后 我可以使用存储的 UserId 导航应用程序视图 一旦我进入设置和选项卡注销 这将清除 User
  • Socket.io 400(错误请求)

    我的服务器上有这段代码 var express require express var routes require routes var user require routes user var http require http var
  • iOS 上的 OpenCV - VideoCapture 属性始终返回 1

    我一直在尝试构建一个简单的 OpenCV iOS 应用程序 该应用程序从捆绑包中加载视频并查询其帧数 持续时间等 然后它将尝试从中获取各个帧 不幸的是 当我使用VideoCapture类中 所有属性返回值 1 然后我尝试导航到frame 1
  • WKWebView 未打开自定义 URL 方案(js 在新窗口中打开自定义方案链接)

    我有一个WKWebView在我的应用程序中 我不使用UIWeb视图 因为由于某种奇怪的原因 它无法正确打开包含大量 JS 代码的网页 当我点击链接时自定义 url 方案 scm 它确实nothing My code void viewDid
  • 从 NavigationController 中删除 ViewController 后 AVPlayer 继续播放

    因此 我在项目中使用 ARC 当我添加 AVPlayerLayer 时 它工作得很好 但当我从 UINavigationItem 中弹出 UIViewController 时 视频继续在后台播放 有谁知道你会如何处理这个问题 这似乎是一件很
  • 使 iOS 应用程序与 iPhone 6 和 iPhone 6 尺寸兼容 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我创建了一个应用程序 其中使用 xib 进行布局 目前我使用两种不同的 xib 一种用于iPhone4 320 480 一种用于iPh
  • 将自定义图像设置为 UIBarButtonItem 但它不显示任何图像

    我想将自定义图像设置为 UIBarButtonItem 但它只显示周围的矩形框并且不显示实际图像 func setupBrowserToolbar let browser UIToolbar frame CGRect x 0 y 20 wi
  • 使用 AVFoundation 裁剪 AVAsset 视频

    我在用AVCaptureMovieFileOutput录制一些视频 我使用显示预览层AVLayerVideoGravityResizeAspectFill稍微放大 我遇到的问题是最终的视频较大 包含预览期间不适合屏幕的额外图像 这是预览和生
  • 是否为 Core Data 的获取结果控制器实现委托

    实现四种委托方法有什么好处 void controllerWillChangeContent NSFetchedResultsController 控制器 void 控制器 NSFetchedResultsController 控制器 di
  • ios 在后台处理推送通知

    我想保存应用程序处于后台状态时到达的推送通知 我知道关于 void application UIApplication application didReceiveRemoteNotification NSDictionary userIn
  • 可以获取位置,但无法获取航向

    我目前只使用模拟器 但我在 iOS 模拟器上快速使用 CoreLocation 时遇到问题 我得到此代码打印的位置更新 但从未得到标题 我不想当然 我正在尝试制作一个指南针类型的应用程序 它将显示目标的方位 class CompassVie
  • AWS S3 公共对象与私有对象?

    回到 S3 我的存储桶中有图像的 URL 我将在我的应用程序中呈现这些图像 但它们被设置为私有 当我尝试单击该链接时 它显示 访问被拒绝 当我将链接的设置更改为公共时 它会通过 但是我读到公共访问并不是最安全的事情 所以这本质上是一个由两部
  • 企业发行版在 Swift 应用程序中与 iOS8 配合不佳

    我在使用 swift 应用程序在 iOS 8 设备上运行 Enterprise 版本时遇到问题 如果我使用非企业帐户进行代码签名 它似乎工作正常 有人遇到这个问题吗 以下是我在尝试使用企业帐户运行构建以进行协同设计时在 iOS 设备上收到的

随机推荐