我想将NSValue转换为NSNumber。这段代码有什么问题?
char value[4];
[myNSValue getValue:(void*)value];
NSNumber *number = [[NSNumber alloc] initWithBytes:(void*)value objCType:[myNSValue objCType]];
NSTimeInterval duration = [number intValue];
它导致最后一行崩溃。这会发生什么?
答案 0 :(得分:2)
在上面的评论中诊断为@ ale0xB,NSNumber
方法的-initWithBytes:objCType:
doesn't actually provide its own implementation;所以,当你调用那个选择器时,你实际上得到了来自NSNumber
基类NSValue
的实现。 [[NSNumber alloc] initWithBytes:foo objCType:bar]
和[[NSValue alloc] initWithBytes:foo objCType:bar]
之间没有 1 差异 - 它们都调用相同的方法实现,它释放它给出的self
并返回一个新对象通常是NSConcreteValue
类型(NSValue
的未记录的子类,但不是NSNumber
的子类。)
更清楚:
#import <assert.h>
#import <Foundation/Foundation.h>
int main()
{
id x;
x = [NSNumber numberWithInt:42];
assert( [x isKindOfClass:[NSNumber class]] );
assert( [x respondsToSelector:@selector(intValue)] );
int fortytwo = 42;
x = [[NSNumber alloc] initWithBytes:&fortytwo objCType:@encode(int)];
assert( [x isKindOfClass:[NSValue class]] );
assert( ! [x isKindOfClass:[NSNumber class]] ); // yikes!
assert( ! [x respondsToSelector:@selector(intValue)] ); // your particular problem
}
然而,类别拯救!MartinHäcker编写了一个类别NSNumber(CreatingFromArbitraryTypes)
,可以根据您的需要进行调整。请参阅公共域源代码here。 2 基本思路是针对每种可能的类型编码进行特殊处理:
"i"
进行编码,请发送至-numberWithInt:
; "f"
进行编码,请发送至-numberWithFloat:
; 等等。这很乏味;但是,一旦您编写了一次代码,就可以使用此后的类别,只需调用[NSNumber numberWithValue:myNSValue]
。
( 1 - 或多或少。在这种背景下没有区别,我会说。)
( 2 - 该代码有一些错误,特别是在以后的版本中。请参阅my patch here。)
答案 1 :(得分:1)
请阅读上面的评论以获得进一步的解释。
要实现您想要的功能,只需使用您的(char *)初始化NSString,然后调用NSString的intValue。 - 假设你知道类型,如果没有看下面的评论 -
干杯