设置 NSObject 属性 - EXC_BAD_ACCESS

Set NSObject property - EXC_BAD_ACCESS

进程:

对象似乎没有正确的内存访问。

我希望用户可以切换视图控制器,即使有待处理的请求,应用程序也不会崩溃。

我不想在加载期间在视图控制器上阻止用户。

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

编辑:

我只是将 @property (nonatomic) User *user; 放入 MyController.h 并删除 User *user; 放入 MyController.m 。用户没有被释放,也没有崩溃。

  • 验证 [dict objectForKey:@"infos"] 不是 NSNull - 崩溃 可以在这里。
  • 其他代码看起来没问题。
  • 同时将 -(void)dealloc 添加到您的对象中并放置一个 断点在那里验证对象没有被释放 作业之前。

NSError

检查你的输出
  NSError *error;
  NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

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

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

当您尝试转换 from/to JSON 时,不正确的 JSON 结构将导致它崩溃。有关详细信息,请参阅错误。

通常,当对象被释放但您的代码试图访问它的数据时,就会出现这种类型的错误 所以,首先,检查你如何在内存中保存你的用户实体,例如 属性:

@property (nonatomic, strong) User *u;

并确保操作完成后它仍在内存中:

希望对您有所帮助。

而不是

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

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

设置断点,分别检查infoDict、notification、self。这消除了猜测。现在你甚至不知道这三个作业中哪一个出了问题。

并且由于您认为有很多代码行没有错误且无关紧要,因此实际错误很可能隐藏在这些行中的某个地方。请记住:您的代码中存在错误。假设您的任何代码都没有错误是愚蠢的,因为您已经知道它不是!