如何使用 RKMappingOperation 将本地 NSDictionary 映射到自定义对象?
Posted
技术标签:
【中文标题】如何使用 RKMappingOperation 将本地 NSDictionary 映射到自定义对象?【英文标题】:How to map local NSDictionary into a custom Object using RKMappingOperation? 【发布时间】:2015-11-28 10:11:57 【问题描述】:RJobObject * jobObj = [RJobObject new];
RKMappingOperation *mappingOperation = [[RKMappingOperation alloc] initWithSourceObject:jobDictionary destinationObject:jobObj mapping:[RJobObject mapping]];
mappingOperation.dataSource = (id)jobObj;
[mappingOperation start];
jobDictionary structure:
NSDictionary *msg1 = @
@"id" : @"dfcd",
@"message" : @"ndjfcdfcd"
;
NSDictionary *msg2 = @
@"id" : @"fjvdfv",
@"message" : @"kjndcdovc"
;
NSDictionary *msg3 = @
@"id" : @"fce",
@"message" : @"dfcdf"
;
NSArray *msgsArray = [NSArray arrayWithObjects:msg1, msg2,msg3, nil];
NSMutableDictionary * jobDictionary = [NSMutableDictionary dictionaryWithDictionary:@@"id" : @"Sourabh pant",
@"title": @"http://www.google.com"
];
[jobDictionary setObject:msgsArray forKey:@"messages"];
/.................................................. ........../
RJobObject is the custom object:
@property (nonatomic) NSString * id;
@property (nonatomic) long long duration;
@property (nonatomic) NSString * title;
@property (nonatomic) NSString * image;
@property (nonatomic) NSString * secret;
@property (nonatomic) NSInteger unreadCount;
@property (nonatomic) NSArray * messages;
如果 jobDictionary 包含消息,这会在 Rrestkit 内部造成崩溃。如果 jobDictionary 中的消息数组为空,则代码运行正常。 所以总结一下消息数组没有被映射。
堆栈跟踪 2015-11-28 15:59:22.808 检查休息套件[35951:3402596] -
[RJobObject mappingOperation:targetObjectForRepresentation:withMapping:inRelationship:]: unrecognized selector sent to instance 0x79f96270
2015-11-28 16:00:48.987 Checking Rest Kit[35951:3402596] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RJobObject mappingOperation:targetObjectForRepresentation:withMapping:inRelationship:]: unrecognized selector sent to instance 0x79f96270'
*** First throw call stack:
(
0 CoreFoundation 0x018e3a14 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x013a2e02 objc_exception_throw + 50
2 CoreFoundation 0x018ecd63 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x0182a6bd ___forwarding___ + 1037
4 CoreFoundation 0x0182a28e _CF_forwarding_prep_0 + 14
5 Checking Rest Kit 0x00142f48 -[RKMappingOperation destinationObjectForMappingRepresentation:parentRepresentation:withMapping:inRelationship:] + 1704
6 Checking Rest Kit 0x00149885 __64-[RKMappingOperation mapOneToManyRelationshipWithValue:mapping:]_block_invoke + 149
7 CoreFoundation 0x018152e9 __53-[__NSArrayI enumerateObjectsWithOptions:usingBlock:]_block_invoke + 73
8 CoreFoundation 0x01815182 -[__NSArrayI enumerateObjectsWithOptions:usingBlock:] + 162
9 CoreFoundation 0x017ff835 -[NSArray enumerateObjectsUsingBlock:] + 53
10 Checking Rest Kit 0x0014920b -[RKMappingOperation mapOneToManyRelationshipWithValue:mapping:] + 2763
11 Checking Rest Kit 0x0014b4fb -[RKMappingOperation applyRelationshipMappings] + 6283
12 Checking Rest Kit 0x0014d7db -[RKMappingOperation main] + 4075
13 Checking Rest Kit 0x0014c7dd -[RKMappingOperation start] + 45
14 Checking Rest Kit 0x000ab866 -[ViewController jobObjectFromJobDictionary:] + 310
15 Checking Rest Kit 0x000ab6d5 -[ViewController fetchJobFromDbForId:] + 85
16 Checking Rest Kit 0x000ab566 -[ViewController viewDidLoad] + 918
17 UIKit 0x01e3b2ae -[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 44
18 UIKit 0x01e3fdce -[UIViewController loadViewIfRequired] + 1384
19 UIKit 0x01e401ed -[UIViewController view] + 35
20 UIKit 0x01cedf94 -[UIWindow addRootViewControllerViewIfPossible] + 69
21 UIKit 0x01cee6b1 -[UIWindow _setHidden:forced:] + 304
22 UIKit 0x01ceea67 -[UIWindow _orderFrontWithoutMakingKey] + 49
23 UIKit 0x01d02118 -[UIWindow makeKeyAndVisible] + 80
24 UIKit 0x01c6a6e7 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4190
25 UIKit 0x01c71cd6 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1989
26 UIKit 0x01c96ee5 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke3218 + 68
27 UIKit 0x01c6e966 -[UIApplication workspaceDidEndTransaction:] + 163
28 FrontBoardServices 0x04c4dc76 __37-[FBSWorkspace clientEndTransaction:]_block_invoke_2 + 71
29 FrontBoardServices 0x04c4d74d __40-[FBSWorkspace _performDelegateCallOut:]_block_invoke + 54
30 FrontBoardServices 0x04c6b173 -[FBSSerialQueue _performNext] + 184
31 FrontBoardServices 0x04c6b5aa -[FBSSerialQueue _performNextFromRunLoopSource] + 52
32 FrontBoardServices 0x04c6a8a6 FBSSerialQueueRunLoopSourceHandler + 33
33 CoreFoundation 0x017fd6ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
34 CoreFoundation 0x017f338b __CFRunLoopDoSources0 + 523
35 CoreFoundation 0x017f27a8 __CFRunLoopRun + 1032
36 CoreFoundation 0x017f20e6 CFRunLoopRunSpecific + 470
37 CoreFoundation 0x017f1efb CFRunLoopRunInMode + 123
38 UIKit 0x01c6e206 -[UIApplication _run] + 540
39 UIKit 0x01c73bfa UIApplicationMain + 160
40 Checking Rest Kit 0x000af02a main + 138
41 libdyld.dylib 0x03911a21 start + 1
42 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
In Rconnection.m
- (id)destinationObjectForMappingRepresentation:(id)representation parentRepresentation:(id)parentRepresentation withMapping:(RKMapping *)mapping inRelationship:(RKRelationshipMapping *)relationshipMapping
/* Some Code */
............
if (destinationObject == nil)
NSDictionary *dictionaryRepresentation = [representation isKindOfClass:[NSDictionary class]] ? representation : @ [NSNull null] : representation ;
RKMappingMetadata *parentMetadata = [RKMappingMetadata new];
parentMetadata.parentObject = self.destinationObject ?: [NSNull null];
NSArray *metadata = RKInsertInMetadataList(self.metadataList, parentMetadata, nil);
RKMappingSourceObject *sourceObject = [[RKMappingSourceObject alloc] initWithObject:dictionaryRepresentation parentObject:parentRepresentation rootObject:self.rootSourceObject metadata:metadata];
// Crashing Breakpoint below:
destinationObject = [dataSource mappingOperation:self targetObjectForRepresentation:(NSDictionary *)sourceObject withMapping:concreteMapping inRelationship:relationshipMapping];
.......
/* Some code */
#import <Foundation/Foundation.h>
#import <RestKit/RestKit.h>
@interface RJobObject : NSObject
@property (nonatomic) NSString * id;
@property (nonatomic) long long duration;
@property (nonatomic) NSString * title;
@property (nonatomic) NSString * image;
@property (nonatomic) NSString * secret;
@property (nonatomic) NSInteger unreadCount;
@property (nonatomic) NSArray * messages;
+(RKObjectMapping *)mapping;
@end
【问题讨论】:
提供崩溃的详细信息。消息被映射到不同的类类型?猜测这是一个数据源问题,没有创建该类的实例(或者没有响应适当的选择器)。 请包含完整的RJObject头文件(或至少@interface声明) @Wain 添加了堆栈跟踪。你可以看看。 【参考方案1】:此行不正确:
mappingOperation.dataSource = (id)jobObj;
因为您为操作提供了一个纯数据模型对象作为数据源(并通过强制转换为 id
来告诉编译器喜欢它)。
当操作运行时,它需要创建一些新实例,以便将 JSON dict 中的内容映射到它们中,这是数据源应该做的工作。当操作询问数据源时,您会遇到崩溃,因为您作为数据源提供的对象jobObj
不理解请求。
您需要创建和设置可以处理此要求的适当数据源。
【讨论】:
以上是关于如何使用 RKMappingOperation 将本地 NSDictionary 映射到自定义对象?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 CameraX 与 PreviewView 一起使用?
如何将 groupBy 与 MagicalRecord 一起使用?