0

我为每个服务调用在单例中创建我的 RestKit 映射,例如:

- (void)setupMapping
{
RKObjectManager *objectManager = [RKObjectManager sharedManager];
RKEntityMapping *challengesMapping  = [RKEntityMapping    mappingForEntityForName:@"Challenge" inManagedObjectStore:[objectManager managedObjectStore]];

[challengesMapping addAttributeMappingsFromDictionary:@{
 @"uuid": @"uuid",
 @"title": @"title",
 @"description": @"challengeDescription",
 @"icon": @"icon",
 @"active_from": @"activeFrom",
 @"active_to": @"activeTo",
 @"trigger": @"trigger",
 @"show_in_feed": @"showInFeed",
 @"points": @"points",
 @"trigger": @"trigger",
 @"type": @"type",
 @"min_level": @"minLevel"
 }];
 challengesMapping.identificationAttributes = @[ @"uuid" ];

RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:challengesMapping
                                                                                   pathPattern:CHALLENGE_PATH
                                                                                       keyPath:@"challenges"
                                                                                   statusCodes:[NSIndexSet indexSetWithIndex:SUCCESS]];
[objectManager addResponseDescriptor:responseDescriptor];

RKObjectMapping *sessionMapping = [RKObjectMapping mappingForClass:[TimeStamp class]];
[sessionMapping addAttributeMappingsFromArray:@[@"ts"]];

[objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:sessionMapping
                                                                             pathPattern:CHALLENGE_PATH
                                                                                 keyPath:nil
                                                                            statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];

}

- (void)setupMapping
{
   RKObjectManager *objectManager = [RKObjectManager sharedManager];
RKEntityMapping *festivalsMapping  = [RKEntityMapping mappingForEntityForName:@"Festival" inManagedObjectStore:[objectManager managedObjectStore]];

[festivalsMapping addAttributeMappingsFromDictionary:@{
 @"uuid": @"uuid",
 @"festival": @"festivalDescription",
 @"start_ts": @"start_ts",
 @"end_ts": @"end_ts",
 @"title": @"title"
 }];
festivalsMapping.identificationAttributes = @[ @"uuid" ];

RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:festivalsMapping
                                                                                   pathPattern:GET_FESTIVALS_PATH
                                                                                       keyPath:@"festivals"
                                                                                   statusCodes:[NSIndexSet indexSetWithIndex:SUCCESS]];
[objectManager addResponseDescriptor:responseDescriptor];
RKObjectMapping* sessionMapping = [RKObjectMapping mappingForClass:[TimeStamp class]];
[sessionMapping addAttributeMappingsFromArray:@[@"ts"]];

[objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:sessionMapping
                                                                             pathPattern:GET_FESTIVALS_PATH
                                                                                 keyPath:nil
                                                                            statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];
}

第一个映射(挑战)的第一个服务器调用工作正常,但是当我调用第二个(节日映射)时,我得到错误:“对象的持久存储无法从此 NSManagedObjectContext 的协调器访问”。我知道这可能是 Core Data 中的一个线程问题,但我在我的代码中找不到原因。

我在控制台中得到以下信息:

(lldb)po $r0 错误:无法实现结构:无法读取 r0(实现)执行时出错,无法 PrepareToExecuteJITExpression(lldb)寄存器读取通用寄存器:r4 = 0x00000000 r5 = 0x00066e95 MyApp main + 1 at main.m:14 r6 = 0x00000000 r7 = 0x2fd9ccf8 r8 = 0x2fd9cd10 r10 = 0x00000000 r11 = 0x00000000 r12 = 0x00000148 sp = 0x2fd9ccd4 lr = 0x00066f09 MyAppmain + 117在 main.m:16 pc = 0x00066f09 MyApp`main + 117 在 main.m:16 cpsr = 0x00000010 5 个寄存器不可用。

编辑

这是服务/映射类之一的完整示例。我以前见过类似的模式,即使用 GCD 单例。我也不认为 TimeStamp 根据下面的评论是重复的,因为 pathPatterns 是不同的。正确的?我确实尝试删除它们,但同样的问题。这是预期的,因为它们没有得到 Core Data 的支持

#import "ChallengeService.h"

static ChallengeService __strong *defaultService = nil;

#define CHALLENGE_PATH @"/api/challenges"

@implementation ChallengeService

+ (ChallengeService *)defaultService
{
static dispatch_once_t pred;
dispatch_once(&pred, ^{
    defaultService = [[self alloc] initWithPath:CHALLENGE_PATH];
    [defaultService setupMapping];
});

return defaultService;
}

- (void)setupMapping
{
RKObjectManager *objectManager = [RKObjectManager sharedManager];
RKEntityMapping *challengesMapping  = [RKEntityMapping     mappingForEntityForName:@"Challenge" inManagedObjectStore:[objectManager managedObjectStore]];

[challengesMapping addAttributeMappingsFromDictionary:@{
 @"uuid": @"uuid",
 @"title": @"title",
 @"description": @"challengeDescription",
 @"icon": @"icon",
 @"active_from": @"activeFrom",
 @"active_to": @"activeTo",
 @"trigger": @"trigger",
 @"show_in_feed": @"showInFeed",
 @"points": @"points",
 @"trigger": @"trigger",
 @"type": @"type",
 @"min_level": @"minLevel"
 }];
 challengesMapping.identificationAttributes = @[ @"uuid" ];

RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor    responseDescriptorWithMapping:challengesMapping
                                                                                      pathPattern:CHALLENGE_PATH
                                                                                           keyPath:@"challenges"
                                                                                   statusCodes:[NSIndexSet indexSetWithIndex:SUCCESS]];
[objectManager addResponseDescriptor:responseDescriptor];

RKObjectMapping *sessionMapping = [RKObjectMapping mappingForClass:[TimeStamp class]];
[sessionMapping addAttributeMappingsFromArray:@[@"ts"]];

[objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:sessionMapping
                                                                             pathPattern:CHALLENGE_PATH
                                                                                 keyPath:nil
                                                                            statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]; }

- (void)getChallengesFromDate:(NSDate *)date
                onSuccess:(DidSucceedBlock)successBlock
                  onError:(DidFailWithErrorBlock)failBlock
{    
[defaultService getWithData:nil
                   fromDate:date
                     onLoad:^(id object) {
                         successBlock(object);
                     } onError:^(NSError *error) {
    failBlock(error);
}];

}
4

1 回答 1

0

首先,您不能多次将相同的映射添加到同一个对象管理器。考虑使用多个不同的对象管理器(每组请求一个,即每个单例一个)或预先定义公共映射。

然后,在您的问题中添加有关何时创建和配置这些单例的详细信息。它们中的任何一个是在后台线程上运行还是在应用程序启动时预先完成所有配置。如果您知道应用程序每次使用时都会使用所有配置,那么请提前做好所有事情,因为构建配置的成本很低。

您需要小心,defaultService因为目前您会将访问器方法与静态变量混淆。在方法内定义静态变量并命名_defaultService。然后,您应该将 setup 方法移入initWithPath,因为它是初始化的一部分。确保您正确调用了访问器方法,并且您没有从后台线程调用它(至少是第一次,并且可能是每次)。

于 2013-04-22T06:32:03.890 回答