NSValue到NSNumber转换崩溃

时间:2012-09-25 14:50:50

标签: iphone objective-c ios nsnumber nsvalue

我想将NSValue转换为NSNumber。这段代码有什么问题?

char value[4];
[myNSValue getValue:(void*)value];
NSNumber *number = [[NSNumber alloc] initWithBytes:(void*)value objCType:[myNSValue objCType]];
NSTimeInterval duration = [number intValue];

它导致最后一行崩溃。这会发生什么?

2 个答案:

答案 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。 - 假设你知道类型,如果没有看下面的评论 -

干杯