2013-04-22 3 views
0

Я создаю мои RestKit отображения в одноточечного для каждого вызова службы, такие как:Несколько RKResponseDescriptors вызывая аварии с Core Data с 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) Ро $ r0 об ошибке: Не удалось материализовать-структуру: Не удалось прочитать r0 (материализации) Errored в Execute, не мог 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 MyApp основной + 117 на main.m: 16 шт = 0x00066f09 MyApp`main + 117 при main.m: 16 CPSR = 0x00000010 5 регистров были недоступны.

EDIT

Вот полный пример одного из классов обслуживания/отображения. Я видел аналогичную модель, используемую ранее, то есть с использованием одноточечного GCD. Я также не думаю, что TimeStamp дублируется в комментарии ниже, потому что pathPatterns разные. Верный? Я попытался удалить их, но та же проблема. Который, как ожидается, потому что они не подкреплены основных данных

#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); 
}]; 

} 

ответ

0

Во-первых, вы не можете добавить такое же отображение к одному менеджеру объекта несколько раз. Рассмотрите возможность использования нескольких разных диспетчеров объектов (по одному для каждого набора запросов, например, по одному для каждого синглтона) или определения общих сопоставлений вверх.

Затем добавьте подробную информацию к вашему вопросу о том, когда вы создаете и настраиваете каждый из этих синглетонов. Кто-нибудь из них работает в фоновом потоке или все настройки выполняются с самого начала при запуске приложения. Если вы знаете, что приложение будет использовать все конфигурации каждый раз, когда оно будет использоваться, тогда все будет в порядке, так как для создания конфигурации мало затрат.

Вы должны быть осторожны с вашим defaultService, так как в настоящее время вы будете путать метод доступа со статической переменной. Определите статическую переменную внутри метода и назовите ее _defaultService. Затем вы должны переместить метод установки в initWithPath, поскольку это часть инициализации. Убедитесь, что вы правильно вызываете метод доступа и не вызываете его (по крайней мере в первый раз и, вероятно, каждый раз) из фонового потока.

+0

Редактировать исходное сообщение с дополнительным кодом и комментариями. – Shocks

Смежные вопросы