Наследование 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 объект ожидается. Это может предотвратить глупые ошибки, когда вы по ошибке игнорируете валюту, так что это, вероятно, хорошая мера безопасности.

Другие вопросы по тегам