2013-04-22 90 views
0

多RKResponseDescriptors我在每一個服務調用一個單獨創建我RestKit映射,如:導致崩潰與核心數據與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 = 00000000 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 PC = 0x00066f09 MyApp`main + 117的main.m:16 CPSR = 0x00000010 5個寄存器不可用。

編輯

這裏的服務/映射類之一的完整的例子。我看到過之前使用過類似的模式,即使用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 2013-04-22 09:56:17