NSNumber导致应用程序崩溃

时间:2014-04-11 07:28:37

标签: objective-c nsnumber

我在.h文件中有@property不透明度

@property (assign) NSNumber *opacity;

然后在.m文件中

@synthesize opacity;

然后在

- (id)initWithFrame:(NSRect)frame

我做了

 opacity = [NSNumber numberWithFloat:1.0];

当我运行应用程序时,Xcode显示此错误

Thread 1: EXC_BAD_ACCESS (code-EXC_I386_GPFLT)

但是,如果我将该行更改为

opacity = [NSNumber numberWithInteger:1];

一切正常。

1 个答案:

答案 0 :(得分:3)

看起来它看起来很好。但是你刚刚用NSNumber的实现细节覆盖了这个bug。

正如Volker所指出的,你有一个内存管理问题。您的财产应使用strong。如:

@property (strong) NSNumber *opacity;

在分配值时应该使用该属性。 e.g:

self.opacity = [NSNumber numberWithFloat:1.0];

那为什么它适用于[NSNumber numberWithInteger:1]?因为iOS试图变得聪明。整数1 NSNumber是一个永远不会被释放的单例对象。 [NSNumber numberWithFloat:1.0]不是一个坚不可摧的对象,一旦引用计数降为零,它就会被释放。在您离开创建NSNumber实例的范围后会发生这种情况,因为它永远不会保留在您的代码中。

你可以看到这个小日志代码的单例行为,它记录了NSNumber实例的指针地址:

NSLog(@"Address of `[NSNumber numberWithFloat:1.0]`: %p", [NSNumber numberWithFloat:1.0]);
NSLog(@"Address of `[NSNumber numberWithInteger:1]`: %p", [NSNumber numberWithInteger:1]);

NSLog(@"Address of `[NSNumber numberWithFloat:1.0]`: %p", [NSNumber numberWithFloat:1.0]);
NSLog(@"Address of `[NSNumber numberWithInteger:1]`: %p", [NSNumber numberWithInteger:1]);

产生

Address of `[NSNumber numberWithFloat:1.0]`: 0x10c622d10
Address of `[NSNumber numberWithInteger:1]`: 0xb000000000000013
Address of `[NSNumber numberWithFloat:1.0]`: 0x10c129fb0
Address of `[NSNumber numberWithInteger:1]`: 0xb000000000000013

正如您所看到的,numberWithFloat:1.0中的两个地址不同,numberWithInteger:1中的两个地址相同。因为[NSNumber numberWithInteger:1]始终返回相同的对象。