7

Crashlog:

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

libobjc.A.dylib - objc_msgSend - isEqual:
CoreFoundation  - -[__NSDictionaryM setObject:forKey:]

Code:

if (object) {
    [_objects setObject:object forKey:key];
}

When init of _objects happens earlier in code:

- (id)init {
     self = [super init];
     if (self) {
         _objects = [[NSMutableDictionary alloc] init];
     }
     return self;
}

Object can be nil value, thats why I'm checking if it exist:

AFHTTPRequestOperation *object = [[AFHTTPRequestOperation alloc] initWithRequest:request];

I'm not sure what exactly can cause it. Crash happens very rarely, I'm unable to reproduce it, however a few users got it. I assume something got deallocated, could it be that _objects is nil? Or whole controller got deallocated? Why I can see isEqual in the log?

Can this fix the issue?

if (object && _objects) {
    [_objects setObject:object forKey:key];
}
Nat
  • 12,032
  • 9
  • 56
  • 103
  • Can you post more code? Initialization of dictionary and object? – Pooja M. Bohora Mar 26 '14 at 07:15
  • 1
    for object deallocation unable zombies objects in your xcode for more details. http://stackoverflow.com/questions/20109022/tracking-down-zombies-with-xcode-5-on-ios6 – Sunny Shah Mar 26 '14 at 07:18
  • @Vive: are you sure your key will not be nil? – Pooja M. Bohora Mar 26 '14 at 07:20
  • @Sunnyshah Yes, I'm using ARC. Don't zombies turn off automatically in release mode? – Nat Mar 26 '14 at 07:21
  • 2
    `NSDictionary` uses `isEqual` on the `key`. What is your `key`? What does it's `isEqual` method do? The rarity of the crash might be because a hash collision has to occur for the `isEqual` method to be called. – Vatev Mar 26 '14 at 07:24
  • @Vatev isEqual must be the default method, I didn't overload it. I'm indeed counting hash for it. How to fix the issue if it comes from hash? – Nat Mar 26 '14 at 07:26
  • Can you post your implementation of `hash`? AFAIK the only requirement for `hash` is that two equal objects must have the same hash. – Vatev Mar 26 '14 at 07:38
  • @Vatev I just realized, rare collisions can always happen in `hash`. I'm checking `![_objects objectForKey:identifier]` and it should be ok now. Thank you for your answer, can you post it separately? I would like to accept it. – Nat Mar 26 '14 at 07:44
  • I don't think that would be a solution - `objectForKey:` will do the same check. Hash collisions are normal and expected, thats why `NSDictionary` calls `isEqual` to make sure the objects are the same. Try to make your `hash` method always return 0 to reproduce the crash. Normally even with a `return 0` `hash` method the dictionary should work (the only difference is that it will get slow with a lot of objects). – Vatev Mar 26 '14 at 07:56
  • @Vatev It's ok, I've check as you said, made `identifier = @"0"`. There is no crash if i check `objectForKey:` because I'm not trying to add different object for the same key. When I'm not adding anything to key, which exists, there is no crash. Can you please add your comment as an answer? – Nat Mar 26 '14 at 08:24

1 Answers1

6

You have checked not null condition for the dictionary and object value. Try to check nil condition for your key of object. There might be a case where key can be nil.

if (object && _objects && key) {
    [_objects setObject:object forKey:key];
}
Pooja M. Bohora
  • 1,311
  • 1
  • 14
  • 42