Set NSObject property - EXC_BAD_ACCESS

593 Views Asked by At

Process :

  • App is on the home view controller and is requesting data on API to set an NSObject property. The request is processing on a private method.
  • User change the view controller to a second view controller (the request is still processing asynchronously)
  • The second view controller is loaded
  • The request is ending and app return EXC_BAD_ACCESS when it setting the object property

It seems the object has not the correct memory access.

I would like than the user can switch view controller, even if there is a request pending, and the application doesn't crash.

I don't want to block the user on the view controller during loading.

User.h

@interface User : NSObject

[...]
@property (nonatomic) NSString *notification;
[...]

-(void) methodName;

@end

User.m

-(void) methodName{

        //there is code around but useless for this problem

        [...]

        NSError *error;
        NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

        self.notification = [[dict objectForKey:@"infos"] objectForKey:@"notification"]; //Here is the EXC_BAD_ACCESS


        [...]

}

MyController.m

@interface MyController ()
@end

User *user;

@implementation HomeCVViewController
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:YES];

    user = [User new];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [user someMethod];

        dispatch_async(dispatch_get_main_queue(), ^{
            [...]//some code
        });
    });
}

@end

EDIT :

I just put @property (nonatomic) User *user; in MyController.h and remove User *user; in MyController.m . The user is not deallocated and there is no crash.

4

There are 4 best solutions below

9
On BEST ANSWER
  • Verify that [dict objectForKey:@"infos"] is not NSNull - Crash can be here.
  • Other code looks OK.
  • Also add -(void)deallocto your object and put a break point there to verify that the object is not being released before the assignment.
0
On

Instead of

self.notification = [[dict objectForKey:@"infos"] objectForKey:@"notification"]; //Here is the EXC_BAD_ACCESS

write

NSDictionary* infoDict = dict [@"infos"];
id notification = infoDict [@"notification"];
self.notification = notification;

set a breakpoint, and examine each of infoDict, notification, and self. That takes the guesswork out of it. Right now you don't even know which of these three assignments goes wrong.

And since you have lots of lines of code that are in your opinion bug free and irrelevant, chances are good that the actual bug is hiding somewhere in those lines. Remember: There is a bug in your code. Assuming that any of your code is bug free is daft, because you already know it isn't!

1
On

Check your output at the NSError

  NSError *error;
  NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

  NSLog(@"%@", error.localizedDescription);  <----- HERE

  self.notification = [[dict objectForKey:@"infos"] objectForKey:@"notification"];

When you try to convert from/to JSON, improper JSON structure will cause it to crash. See the error for more information.

4
On

Usually, this type of error appears when object deallocated but your code try to access it's data so, first of all, check how do you hold your User entity in memory, throw, for example, property:

@property (nonatomic, strong) User *u;

and make sure it is still in memory when operation completed:

Hope this will help you.