设置 NSObject 属性 - EXC_BAD_ACCESS
Set NSObject property - EXC_BAD_ACCESS
进程:
- 应用在主视图控制器上,正在请求 API 上的数据以设置 NSObject 属性。请求正在私有方法上处理。
- 用户将视图控制器更改为第二个视图控制器(请求仍在异步处理)
- 加载第二个视图控制器
- 请求正在结束,app return 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。这消除了猜测。现在你甚至不知道这三个作业中哪一个出了问题。
并且由于您认为有很多代码行没有错误且无关紧要,因此实际错误很可能隐藏在这些行中的某个地方。请记住:您的代码中存在错误。假设您的任何代码都没有错误是愚蠢的,因为您已经知道它不是!
进程:
- 应用在主视图控制器上,正在请求 API 上的数据以设置 NSObject 属性。请求正在私有方法上处理。
- 用户将视图控制器更改为第二个视图控制器(请求仍在异步处理)
- 加载第二个视图控制器
- 请求正在结束,app return 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。这消除了猜测。现在你甚至不知道这三个作业中哪一个出了问题。
并且由于您认为有很多代码行没有错误且无关紧要,因此实际错误很可能隐藏在这些行中的某个地方。请记住:您的代码中存在错误。假设您的任何代码都没有错误是愚蠢的,因为您已经知道它不是!