Owe*_*hao 2 objective-c nsnumber
我在 .h 文件中有一个 @property opacity
@property (assign) NSNumber *opacity;
Run Code Online (Sandbox Code Playgroud)
然后在 .m 文件中我
@synthesize opacity;
Run Code Online (Sandbox Code Playgroud)
然后在
- (id)initWithFrame:(NSRect)frame
Run Code Online (Sandbox Code Playgroud)
我做了
opacity = [NSNumber numberWithFloat:1.0];
Run Code Online (Sandbox Code Playgroud)
当我运行应用程序时,Xcode 显示此错误
Thread 1: EXC_BAD_ACCESS (code-EXC_I386_GPFLT)
Run Code Online (Sandbox Code Playgroud)
但是,如果我将该行更改为
opacity = [NSNumber numberWithInteger:1];
Run Code Online (Sandbox Code Playgroud)
一切正常。
看起来它工作正常。但是您刚刚使用 NSNumber 的实现细节覆盖了该错误。
正如沃尔克指出的那样,您有内存管理问题。您的财产应使用strong. 如:
@property (strong) NSNumber *opacity;
Run Code Online (Sandbox Code Playgroud)
并且您应该在分配值时使用该属性。例如:
self.opacity = [NSNumber numberWithFloat:1.0];
Run Code Online (Sandbox Code Playgroud)
那么为什么它与[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]);
Run Code Online (Sandbox Code Playgroud)
这产生
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
Run Code Online (Sandbox Code Playgroud)
如您所见,来自的两个地址numberWithFloat:1.0不同,来自的两个地址numberWithInteger:1相同。因为[NSNumber numberWithInteger:1]总是返回相同的对象。