为什么创建 NSDecimalNumber 会崩溃?
Why does this Creation of NSDecimalNumber crash?
我正在从云服务下载一些值作为 JSON 对象并将它们分配给 NSString 对象,如下所示
NSString *price = [orpObjectDict objectForKey:@"price"];
NSString *qty = [orpObjectDict objectForKey:@"qty"];
我的调试输出显示两个字符串的值如下
NSLog(@"price: %@ <--> qty: %@", price, qty);
2017-04-17 16:29:05.665043 NWMobileTill[1490:730225] price: 6.95 <--> qty: 1
但是下面使用这些 NSString 创建 NSDecimalNumber 失败了
NSDecimalNumber *priceNumber = [NSDecimalNumber decimalNumberWithString:price];
NSDecimalNumber *qtyNumber = [NSDecimalNumber decimalNumberWithString:qty];
017-04-17 16:29:05.665886 NWMobileTill[1490:730225] -[__NSCFNumber length]: unrecognized selector sent to instance 0x174226240
2017-04-17 16:29:05.668080 NWMobileTill[1490:730225] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0x174226240'
*** First throw call stack:
(0x1926fd1b8 0x19113455c 0x192704268 0x192701270 0x1925fa80c 0x19323658c 0x1932340f0 0x193234754 0x1000d9078 0x192cff1e8 0x192d17120 0x1931ebfb0 0x193130aa8 0x1931210a4 0x1931ee35c 0x1006c5218 0x1006d2aec 0x1006c8ce0 0x1006d4e2c 0x1006d4b78 0x19178f2a0 0x19178ed8c)
libc++abi.dylib: terminating with uncaught exception of type NSException
为什么这个简单的创建会崩溃?
您可以使用 NSDecimalNumber 通过键直接检索您的对象:
NSDictionary*orpObjectDict = @{
@"price" : @(5.4),
@"qty" : @(2)
};
NSString *price = [orpObjectDict objectForKey:@"price"];
NSLog(@"string price %@", price);
NSString *qty = [orpObjectDict objectForKey:@"qty"];
NSLog(@"string qty %@", qty);
NSDecimalNumber*dPrice = [orpObjectDict objectForKey:@"price"];
NSLog(@"decimal price %@", dPrice);
NSDecimalNumber *dqty = [orpObjectDict objectForKey:@"qty"];
NSLog(@"decimal quantity %@", dqty);
输出是:
2017-04-17 10:46:12.932 test[2836:50653] string price 5.4
2017-04-17 10:46:12.932 test[2836:50653] string qty 2
2017-04-17 10:46:12.933 test[2836:50653] decimal price 5.4
2017-04-17 10:46:12.933 test[2836:50653] decimal quantity 2
您始终可以使用 isKindOfClass
或 isMemberOfClass
检查 return 对象类型,后者更具限制性。
根据经验,在分配之前确保字典包含键及其不是 nil
的值:
id value = dictionary[key];
if (value) {...}
或为了更好的检查:
if (value && value != [NSNull null]) {...}
编辑
我认为 Objective C 类型管理比 Swift 弱。无论如何使用 [NSDecimalNumber alloc] initWithString:
方法为您提供正确的实例。
NSDictionary*orpObjectDict = @{
@"price" : @"5.4",
@"qty" : @(2)
};
NSString* price = [orpObjectDict objectForKey:@"price"];
NSLog(@"string price %@", price);
NSDecimalNumber*decimalPrice = [[NSDecimalNumber alloc] initWithString:price];
if ([decimalPrice isMemberOfClass:NSDecimalNumber.class]) {
NSLog(@"dqty is a NSDecimalNumber");
}
错误信息
[__NSCFNumber length]: unrecognized selector sent to instance 0x174226240
非常清楚:它表明键 price
的对象是一个 NSNumber
对象。
因此您必须从 NSNumber
:
创建一个 NSDecimalNumber
NSNumber *price = orpObjectDict[@"price"];
NSDecimalNumber *priceNumber = [NSDecimalNumber decimalNumberWithDecimal:price.decimalValue];
您正在获取 Number 并且您正在将代码编写为字符串
请按字符串格式写成此代码
NSString *price = [NSString stringWithFormat:@"%@", orpObjectDict objectForKey:@"price"];
NSString *qty = [ [NSString stringWithFormat:@"%@",orpObjectDict objectForKey:@"qty"];
或简单地检查
if [price isKindOfClass:[NSString class]]
{ // It is string
}
else if [price isKindOfClass:[NSNumber class]]
{
// It is number
}
我正在从云服务下载一些值作为 JSON 对象并将它们分配给 NSString 对象,如下所示
NSString *price = [orpObjectDict objectForKey:@"price"];
NSString *qty = [orpObjectDict objectForKey:@"qty"];
我的调试输出显示两个字符串的值如下
NSLog(@"price: %@ <--> qty: %@", price, qty);
2017-04-17 16:29:05.665043 NWMobileTill[1490:730225] price: 6.95 <--> qty: 1
但是下面使用这些 NSString 创建 NSDecimalNumber 失败了
NSDecimalNumber *priceNumber = [NSDecimalNumber decimalNumberWithString:price];
NSDecimalNumber *qtyNumber = [NSDecimalNumber decimalNumberWithString:qty];
017-04-17 16:29:05.665886 NWMobileTill[1490:730225] -[__NSCFNumber length]: unrecognized selector sent to instance 0x174226240
2017-04-17 16:29:05.668080 NWMobileTill[1490:730225] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0x174226240'
*** First throw call stack:
(0x1926fd1b8 0x19113455c 0x192704268 0x192701270 0x1925fa80c 0x19323658c 0x1932340f0 0x193234754 0x1000d9078 0x192cff1e8 0x192d17120 0x1931ebfb0 0x193130aa8 0x1931210a4 0x1931ee35c 0x1006c5218 0x1006d2aec 0x1006c8ce0 0x1006d4e2c 0x1006d4b78 0x19178f2a0 0x19178ed8c)
libc++abi.dylib: terminating with uncaught exception of type NSException
为什么这个简单的创建会崩溃?
您可以使用 NSDecimalNumber 通过键直接检索您的对象:
NSDictionary*orpObjectDict = @{
@"price" : @(5.4),
@"qty" : @(2)
};
NSString *price = [orpObjectDict objectForKey:@"price"];
NSLog(@"string price %@", price);
NSString *qty = [orpObjectDict objectForKey:@"qty"];
NSLog(@"string qty %@", qty);
NSDecimalNumber*dPrice = [orpObjectDict objectForKey:@"price"];
NSLog(@"decimal price %@", dPrice);
NSDecimalNumber *dqty = [orpObjectDict objectForKey:@"qty"];
NSLog(@"decimal quantity %@", dqty);
输出是:
2017-04-17 10:46:12.932 test[2836:50653] string price 5.4
2017-04-17 10:46:12.932 test[2836:50653] string qty 2
2017-04-17 10:46:12.933 test[2836:50653] decimal price 5.4
2017-04-17 10:46:12.933 test[2836:50653] decimal quantity 2
您始终可以使用 isKindOfClass
或 isMemberOfClass
检查 return 对象类型,后者更具限制性。
根据经验,在分配之前确保字典包含键及其不是 nil
的值:
id value = dictionary[key];
if (value) {...}
或为了更好的检查:
if (value && value != [NSNull null]) {...}
编辑
我认为 Objective C 类型管理比 Swift 弱。无论如何使用 [NSDecimalNumber alloc] initWithString:
方法为您提供正确的实例。
NSDictionary*orpObjectDict = @{
@"price" : @"5.4",
@"qty" : @(2)
};
NSString* price = [orpObjectDict objectForKey:@"price"];
NSLog(@"string price %@", price);
NSDecimalNumber*decimalPrice = [[NSDecimalNumber alloc] initWithString:price];
if ([decimalPrice isMemberOfClass:NSDecimalNumber.class]) {
NSLog(@"dqty is a NSDecimalNumber");
}
错误信息
[__NSCFNumber length]: unrecognized selector sent to instance 0x174226240
非常清楚:它表明键 price
的对象是一个 NSNumber
对象。
因此您必须从 NSNumber
:
NSDecimalNumber
NSNumber *price = orpObjectDict[@"price"];
NSDecimalNumber *priceNumber = [NSDecimalNumber decimalNumberWithDecimal:price.decimalValue];
您正在获取 Number 并且您正在将代码编写为字符串
请按字符串格式写成此代码
NSString *price = [NSString stringWithFormat:@"%@", orpObjectDict objectForKey:@"price"];
NSString *qty = [ [NSString stringWithFormat:@"%@",orpObjectDict objectForKey:@"qty"];
或简单地检查
if [price isKindOfClass:[NSString class]]
{ // It is string
}
else if [price isKindOfClass:[NSNumber class]]
{
// It is number
}