我正在尝试创建扩展NSDecimalNumber的Price类,但在尝试分配它时,init会引发异常。知道什么可能是个问题吗?
*** 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,则会出现相同的异常。我放弃了......
答案 0 :(得分:4)
NSDecimalNumber
继承NSNumber
,即class cluster。这使得继承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
个对象的位置。当你错误地忽视货币时,这有可能防止愚蠢的错误,所以这可能是一个很好的安全措施。