Наследование NSDecimalNumber
Я пытаюсь создать класс Price, который расширяет NSDecimalNumber, но при попытке выделить его и инициализировать он вызывает исключения. Есть идеи, в чем может быть проблема?
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Did you forget to nest alloc and initWithString: ?'
Price.h
#import <Foundation/Foundation.h>
@interface Price : NSDecimalNumber
+ (Price*)priceWithString:(NSString*)val;
@end
Price.m
#import "Price.h"
@implementation Price
- (NSString *)description {
return [[super description] stringByAppendingString:@" €"];
}
+ (Price*)priceWithString:(NSString*)val {
return [[Price alloc] initWithString:val];
}
@end
Редактировать: даже голый класс не работает. Если я расширяю NSDecimalNumber, а затем пытаюсь сделать alloc init, то же исключение. Я сдался на этом...
1 ответ
NSDecimalNumber
наследуется NSNumber
, который является кластером классов. Это делает его очень сложным для наследования NSDecimalNumber
потому что существует ряд дополнительных требований для такого наследования. Согласно документации Apple, ваш класс должен
- Быть подклассом абстрактного суперкласса кластера
- Объявить свое собственное хранилище
- Переопределить все методы инициализатора суперкласса
- Переопределить примитивные методы суперкласса (описано ниже)
В вашем случае ваш Price
класс должен будет повторно реализовать много NSDecimalNumber
, что, вероятно, слишком много работы.
Лучшим подходом было бы гнездиться NSDecimalNumber
внутри вашего Price
класс и добавьте метод для получения его числового значения, например:
@interface Price : NSObject
/// Represents the numeric value of the price
@property (nonatomic, readonly) NSDecimalNumber *valueInLocalCurrency;
/// Represents the pricing currency
@property (nonatomic, readonly) NSString *currencyCode;
/// Creates an immutable Price object
-(id)initWithPriceInLocalCurrency:(NSDecimalNumber*)price andCurrencyCode:(NSString*)currencyCode;
@end
Следствием этого решения является то, что вы больше не можете отправлять Price
возражать в местах, где NSDecimalNumber
объект ожидается. Это может предотвратить глупые ошибки, когда вы по ошибке игнорируете валюту, так что это, вероятно, хорошая мера безопасности.