Restkit: сбой methodSignatureForSelector при RKMappingOperation с EXC_BAD_ACCESS

#restkit-0.20

#restkit-0.20

Вопрос:

В файле RKMappingOperation есть метод

 - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
    return [self.object methodSignatureForSelector:selector];
}
  

который вызывает исключение на iPhone5, но приложение продолжает выполняться. Но на iPhone4S приложение выходит из строя с EXC_BAD_ACCESS.

введите описание изображения здесь
введите описание изображения здесь

Я предполагаю, что исключение обрабатывается, как указано в документации:

Вызывает исключение NSInvalidArgumentException. Переопределите этот метод в вашем конкретном подклассе, чтобы вернуть правильный объект NSMethodSignature для данного селектора и класса, к которому относятся ваши прокси-объекты.

Файл журнала:

 T restkit.object_mapping:RKMappingOperation.m:862 Performing mapping operation: <RKMappingOperation 0x181e1960> for 'TSNDecimal' object. Mapping values from object 10 to object <TSNDecimal: 0x18004bc0> (entity: TSNDecimal; id: 0x1819dcb0 <x-coredata:///TSNDecimal/t507A4693-CB2E-4194-966A-00BA8AD5CC70391> ;
    data: {
    number = 0;
    responseName = nil;
    sortId = 0;
    ticket = nil;
}) with object mapping (null)
2014-07-07 13:17:50.194 VZN Mobile[440:8f0f] D restkit.object_mapping:RKPropertyInspector.m:131 Cached property inspection for Class 'TSNDecimal': {
number =     {
    isPrimitive = 0;
    keyValueCodingClass = NSDecimalNumber;
    name = number;
};
responseName =     {
    isPrimitive = 0;
    keyValueCodingClass = NSString;
    name = responseName;
};
sortId =     {
    isPrimitive = 0;
    keyValueCodingClass = NSNumber;
    name = sortId;
};
sortIdValue =     {
    isPrimitive = 1;
    keyValueCodingClass = NSNumber;
    name = sortIdValue;
};
ticket =     {
    isPrimitive = 0;
    keyValueCodingClass = TSNTicketApiTO;
    name = ticket;
};
  

}
2014-07-07 13:17:50.194 VZN Mobile[440:9f07] T restkit.object_mapping:RKMappingOperation.m: 440 Найдено преобразуемое значение в ключевом пути ‘(null)’. Преобразование из класса ‘__NSCFNumber’ в ‘NSDecimalNumber’
2014-07-07 13:17:50.204 VZN Mobile[440:9f07] self.object:10

Комментарии:

1. Покажите ваше сопоставление и JSON, которые вызывают исключение.

Ответ №1:

Спасибо, Уэйн, за комментарий. На самом деле это было вызвано неправильным кодом в Restkit, преобразующим NSDecimalNumber в NSNumber. В RKValueTransformers.m есть метод:

   (instancetype)decimalNumberToNumberValueTransformer
{
    ....
    ....
    RKValueTransformerTestOutputValueClassIsSubclassOfClass(outputValueClass, (@[ [NSNumber class], [NSDecimalNumber class]]), error);
    if ([inputValue isKindOfClass:[NSNumber class]]) {
        *outputValue = [NSDecimalNumber decimalNumberWithDecimal:[inputValue decimalValue]];
    } else if ([inputValue isKindOfClass:[NSDecimalNumber class]]) {
        *outputValue = inputValue;
    }
    return YES;
}];
}
  

Условия должны быть заменены таким образом:

     if ([inputValue isKindOfClass:[NSDecimalNumber class]]) {
        *outputValue = [NSDecimalNumber decimalNumberWithDecimal:[inputValue decimalValue]];
    } else if ([inputValue isKindOfClass:[NSNumber class]]) {
        *outputValue = inputValue;
    }
  

Тогда сбой кода не происходит, и он работает так, как первоначально предполагал автор.

Комментарии:

1. Ваше исправление выглядит не совсем корректным / согласованным (одна ветвь возвращает NSNumber , а другая возвращает NSDecimalNumber ), и вам следует отправить отчет об ошибке на github, если вы еще этого не сделали

2. Вы правы. На этом я тоже остановился. Но я был удовлетворен, поскольку NSDecimalNumber является подклассом NSNumber.