Reputation: 3355
I have a @property opacity in .h file
@property (assign) NSNumber *opacity;
Then in .m file I
@synthesize opacity;
Then in
- (id)initWithFrame:(NSRect)frame
I did
opacity = [NSNumber numberWithFloat:1.0];
When I run the app, Xcode shows this error
Thread 1: EXC_BAD_ACCESS (code-EXC_I386_GPFLT)
However, if I change that line to
opacity = [NSNumber numberWithInteger:1];
Everything works fine.
Upvotes: 2
Views: 771
Reputation: 90117
It just looks like it works fine. But you have just covered that bug with an implementation detail of NSNumber.
As Volker pointed out you have a memory management problem. Your property should use strong
. As in:
@property (strong) NSNumber *opacity;
And you should use that property when assigning values. e.g.:
self.opacity = [NSNumber numberWithFloat:1.0];
So why does it work with [NSNumber numberWithInteger:1]
? Because iOS tries to be smart. A integer 1 NSNumber is a singleton object which never gets deallocated. [NSNumber numberWithFloat:1.0]
is not such an indestructible object, it will get deallocated once its reference count drops to zero. This happens after you leave the scope where the NSNumber instance was created, because it is never retained in your code.
You can see the singleton behaviour with this little logging code, which logs the pointer address of NSNumber instances:
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]);
which yields
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
As you can see the two addresses from numberWithFloat:1.0
differ, and the two addresses from numberWithInteger:1
are the same. Because [NSNumber numberWithInteger:1]
always returns the same object.
Upvotes: 5