RestKit 模型对象引发 -valueForUndefinedKey: 用于合成属性

Posted

技术标签:

【中文标题】RestKit 模型对象引发 -valueForUndefinedKey: 用于合成属性【英文标题】:RestKit model object raises -valueForUndefinedKey: for a synthesized property 【发布时间】:2013-03-13 20:40:55 【问题描述】:

我正在尝试映射到一个对象,但一直在获取

[<ItemObject 0x100353710> valueForUndefinedKey:]: this class is not key value coding-compliant for the key uid.

ItemObject.h

@interface ItemObject : NSObject

@property (nonatomic, retain) NSNumber * uid;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSString * itemType;

@end

ItemObject.m

@implementation ItemObject

@dynamic uid;
@dynamic title;
@dynamic itemType;

@end

方法

+ (void)searchFeatureById:(NSString *)searchId

    NSLog(@"Search Feature By ID: %@", searchId);
    RKObjectMapping *itemMapping = [RKObjectMapping mappingForClass:[ItemObject class]];

    [itemMapping addAttributeMappingsFromDictionary:@
     @"id": @"uid",
        @"name": @"title",
        @"item_type": @"itemType"
     ];


    RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:itemMapping pathPattern:nil keyPath:@"data" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

    RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
    // The entire value at the source key path containing the errors maps to the message
    [errorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"errorMessage"]];
    NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError);
    // Any response in the 4xx status code range with an "errors" key path uses this mapping
    RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:errorMapping pathPattern:nil keyPath:@"error_description" statusCodes:statusCodes];
    RKObjectManager *manager = [RKObjectManager sharedManager];
    NSLog(@"HTTP Client: %@", manager.HTTPClient);

    [manager addResponseDescriptorsFromArray:@[ responseDescriptor, errorDescriptor ]];
//    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
                            @"false", @"with_lock"
                            , nil];
    NSString *path = [NSString stringWithFormat:@"/api/v1/features/%@", searchId];
    NSLog(@"Manager: %@", manager);
    [manager getObjectsAtPath:path parameters:params success:^(RKObjectRequestOperation *operation, RKMappingResult *result) 
        NSLog(@"Results: %@", result);
        // Handled with articleDescriptor
     failure:^(RKObjectRequestOperation *operation, NSError *error) 
        // Transport error or server error handled by errorDescriptor
        NSLog(@"Error: %@", [error localizedDescription]);
        NSAlert *alert = [NSAlert alertWithMessageText:@"Error" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", [error localizedDescription]];
        [alert runModal];

    ];

JSON 响应


    "data": 
        "id": 1961,
        "item_type": "features",
        "assigned_to": 
        "id": 106
    ,
    "parent": 
        "id": 0
    ,
        "priority": 
        "id": 3
    ,
        "project": 
        "id": 62
    ,
        "release": 
        "id": 180
    ,
        "reported_by": 
        "id": 106
    ,
        "reported_by_customer_contact": 
        "id": 0
    ,
        "status": 
        "id": 6
    ,
        "workflow_step": 
        "id": 10
    ,
        "actual_duration": 
        "duration": 0,
        "time_unit": 
            "id": 2
        
    ,
        "estimated_duration": 
        "duration": 8,
        "time_unit": 
            "id": 2
        
    ,
        "remaining_duration": 
        "duration": 0,
        "time_unit": 
            "id": 2
        
    ,
        "percent_complete": 0,
        "archived": false,
        "publicly_viewable": false,
        "completion_date": "1899-01-01T07:00:00Z",
        "due_date": "1899-01-01T07:00:00Z",
        "start_date": "2013-03-11T07:00:00Z",
        "description": "Create Login GUI",
        "name": "Login View",
        "notes": "",
        "number": "1961",
        "build_number": "",
        "custom_fields": 
            "custom_157": true,
            "custom_180": "",
            "custom_174": "",
            "custom_181": false,
            "custom_179": "",
            "custom_182": "",
            "custom_186": false,
            "custom_156": 0,
            "custom_161": "",
            "custom_163": "",
            "custom_164": "",
            "custom_165": "",
            "custom_167": "",
            "custom_185": []
        
    

崩溃

(
    0   CoreFoundation                      0x00007fff8d39bf56 __exceptionPreprocess + 198
    1   libobjc.A.dylib                     0x00007fff8a7b2d5e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff8d4261b9 -[NSException raise] + 9
    3   Foundation                          0x00007fff9716c703 -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 240
    4   Foundation                          0x00007fff970a338e _NSGetUsingKeyValueGetter + 108
    5   Foundation                          0x00007fff970a3315 -[NSObject(NSKeyValueCoding) valueForKey:] + 392
    6   Foundation                          0x00007fff970c2da2 -[NSObject(NSKeyValueCoding) valueForKeyPath:] + 348
    7   RestKit                             0x0000000100079675 -[RKMappingOperation shouldSetValue:atKeyPath:] + 85
    8   RestKit                             0x000000010007ad9f -[RKMappingOperation applyAttributeMapping:withValue:] + 2079
    9   RestKit                             0x000000010007c028 -[RKMappingOperation applyAttributeMappings:] + 1752
    10  RestKit                             0x00000001000832e0 -[RKMappingOperation main] + 3200
    11  Foundation                          0x00007fff970c56b4 -[__NSOperationInternal start] + 705
    12  RestKit                             0x000000010006c84e -[RKMapperOperation mapRepresentation:toObject:atKeyPath:usingMapping:metadata:] + 1870
    13  RestKit                             0x000000010006afbb -[RKMapperOperation mapRepresentation:atKeyPath:usingMapping:] + 1883
    14  RestKit                             0x000000010006da20 -[RKMapperOperation mapRepresentationOrRepresentations:atKeyPath:usingMapping:] + 832
    15  RestKit                             0x000000010006e26e -[RKMapperOperation mapSourceRepresentationWithMappingsDictionary:] + 1966
    16  RestKit                             0x000000010006ebbf -[RKMapperOperation main] + 1375
    17  Foundation                          0x00007fff970c56b4 -[__NSOperationInternal start] + 705
    18  RestKit                             0x00000001000e8f1c -[RKObjectResponseMapperOperation performMappingWithObject:error:] + 1116
    19  RestKit                             0x00000001000e7347 -[RKResponseMapperOperation main] + 2055
    20  Foundation                          0x00007fff970c56b4 -[__NSOperationInternal start] + 705
    21  Foundation                          0x00007fff970d8912 ____NSOQSchedule_block_invoke_2 + 124
    22  libdispatch.dylib                   0x00007fff8abe1a82 _dispatch_call_block_and_release + 18
    23  libdispatch.dylib                   0x00007fff8abe2961 _dispatch_worker_thread2 + 255
    24  libsystem_c.dylib                   0x00007fff9054c3da _pthread_wqthread + 316
    25  libsystem_c.dylib                   0x00007fff9054db85 start_wqthread + 13

使用 RestKit 0.20.0-rc1 进行 Mac OS X 开发

我做错了什么?如果我添加/删除对象属性,它会为新参数引发相同的键/值错误。这让我相信这不是我的对象的东西,而是关键路径?

更新

它跳转到RKMappingOperation.m文件的第356行。

- (BOOL)shouldSetValue:(id *)value atKeyPath:(NSString *)keyPath

    id currentValue = [self.destinationObject valueForKeyPath:keyPath]; //<-- this line here
    if (currentValue == [NSNull null]) 
        currentValue = nil;
    

@noa 更新 2

2013-03-14 10:11:51.012 Project[55798:6a03] Destination Class: ItemObject
2013-03-14 10:11:51.012 Project[55798:6a03] Destination Class Super: NSObject

添加

[self.destinationObject objectForKey:@"uid"];

日志

2013-03-14 10:16:08.030 Project[55836:2203] -[ItemObject objectForKey:]: unrecognized selector sent to instance 0x103437e80

【问题讨论】:

如果你使用“identifier”而不是“id”,行为会改变吗?您是在 @synthesizing id 属性(或使用最新版本的 Xcode 以便您不需要)? 它没有改变。我什至删除了 Id,然后收到 title 的错误我正在为我准备 xcode 自动合成器。 @JesseRusak 我已经更新了我的代码以防止混淆 你可以为你的 ItemObject 类发布@implementation 吗? 您是否也发布self.destinationObject 的超类链(即NSStringFromClass([self.destinationObject class])NSStringFromClass([[self.destinationObject class] superclass]) 以确认您的类确实被使用?您是否也尝试直接调用[self.destinationObject uid] 【参考方案1】:

您在实现中使用的@dynamic 指令告诉编译器不要为该属性生成方法。由于这些方法不存在,因此您的类与这些键的键值不兼容。 (即 RestKit 正在尝试调用 uid 方法,但它不存在。)

您应该:

删除@dynamic 声明(以便编译器合成所需的方法)或 添加您自己的uidsetUid: 实现

【讨论】:

就是这样!!! GRRRR。说得通。我刚刚复制了我的核心数据控制器并将NSManagedObject更改为NSObject非常感谢!

以上是关于RestKit 模型对象引发 -valueForUndefinedKey: 用于合成属性的主要内容,如果未能解决你的问题,请参考以下文章

RestKit、核心数据和关系问题。父对象不识别子集

如何使用 RestKit 测试这个对象映射

RestKit 发布嵌套的托管对象会创建重复项

RestKit 对象映射与外键和服务

Restkit 0.24.0:如何将对象(包括对多关系)序列化为 JSON

如何在通过 Core Data 保存我的 RestKit 托管对象之前对其进行修改?