2014-01-25 3 views
1

Я пытаюсь создать ценовой класс, который расширяет NSDecimalNumber, но при попытке выделить его и init он создает исключения. Любая идея, что может быть проблемой?Inheriting 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 

Edit: Даже голый класс не работает. Если я расширяю NSDecimalNumber, а затем пытаюсь выполнить alloc init, то такое же исключение. Я сдался при этом ...

+0

Должен использовать 'instancetype' /' self'. – nhgrif

+1

Где ваш метод initWithString: 'в классе' Price'? – dasblinkenlight

ответ

4

NSDecimalNumber наследует NSNumber, что является class cluster. Это очень сложно наследовать NSDecimalNumber, поскольку для такого наследования существует ряд дополнительных требований. Согласно Apple, документации, ваш класс должен

  • быть подкласс абстрактного суперкласса кластера
  • Объявите свои собственные хранения
  • Override все методы инициализаторе суперкласса
  • Override суперкласса примитивные методы (описано ниже)

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

+0

'return [super initWithString: str];'? Если, конечно, ему не нужна пользовательская инициализация. – nhgrif

+0

Я не думаю, что это проблема. Реализация по умолчанию будет вызвана, если он не переопределит ее. –

+0

Я ошибаюсь, вы правы: http://stackoverflow.com/questions/8963078/objective-c-did-you-forget-to-nest-alloc-and-init –