1
votes

I got a problem with the NSTimer and the userInfo.
In the docs Apple writes that the system keeps a strong reference to the Timer (and therefore the userInfo?) though sometimes when I'm trying to access parts of the userInfo object I'm getting a Bad Access exception. (Afaik that means something really bad happened)

Without further ado, here's how my object looks like that I pass to the userInfo:

@interface MyObject

@property (nonatomic, assign) u_int8_t cmd;
@property (nonatomic, assign) NSNumber *_id;

@end

And here's how I set the Timer:

NSTimer *myTimer = [NSTimer timerWithTimeInterval:10 target:self selector:@selector(someMethod:) userInfo:message repeats:NO];
[[NSRunLoop mainRunLoop] myTimer forMode:NSDefaultRunLoopMode];

The method that gets triggered when the Timer fires

-(void) someMethod:(NSTimer *)timer{
    MyObject* mObject = [timer userInfo];
    u_int8_t cmd = mObject.cmd; // This works
    NSNumber *_id = mObject._id; // Bad access
}

Note: The userInfo itself isn't nil. Neither is the u_int8_t nil or whatsoever. But as soon as I try to access the NSNumber object I'm receiving the following exception (not necessarily every time):

Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x00000000

What happens if I add a strong property to the NSNumber object? Would this fix the issue and why? Why does this problem happen in the first place?

2
You are accessing properties that are different from your header definition, can you update your code? - Tomáš Linhart
@TomášLinhart you're right - just updated it, thanks. - user3420815

2 Answers

1
votes

As NSNumber is an object you need to use the strong attribute, which is the default, so change the @property declaration to:

@property (nonatomic) NSNumber *_id;

And using _id as the identifier is a bad idea as id is an Objective-C keyword, and you will likely confuse yourself at some point.

1
votes

The property declaration is wrong. NSNumber is an object. The property type must be strong or copy.

@property (nonatomic, copy) NSNumber *_id;