NSMutableArray接收JSON崩溃,咨询addObject正确使用方法
咱们来拆解你遇到的核心问题,这也是导致崩溃的根本原因:
1. 属性修饰符的错误使用
你声明数组的代码是:
@property (nonatomic, copy) NSMutableArray *arrayDATA;
这里用copy修饰NSMutableArray是非常危险的——因为copy操作对于可变容器类(比如NSMutableArray)来说,会返回一个不可变的副本(也就是NSArray)。虽然你的变量声明是NSMutableArray类型,但实际存储的对象是不可变的NSArray,后续调用addObject:这类可变数组专属方法时,本质是给不可变数组发消息,这本身就会触发崩溃(你这次的崩溃信息看似是objectForKey:的问题,其实是后续取数据时的连锁反应)。
正确的做法是把修饰符改成strong,这样才能保证你持有的是真正的可变数组对象:
@property (nonatomic, strong) NSMutableArray *arrayDATA;
2. addObject:的用法错误
你写的[_arrayDATA addObject:[responseObject objectForKey:@"datalist"]],是把整个datalist数组作为单个元素添加到了arrayDATA里。这时候arrayDATA的结构变成了:
[ [ {id:1, name:"ADPL"}, {id:2, name:"GOOG"}, {id:3, name:"LIKE"} ] ]
也就是数组嵌套数组。当你在tableView:cellForRowAtIndexPath:里尝试取元素并调用objectForKey:@"name"时,拿到的其实是内层的数组,而NSArray根本没有objectForKey:方法,这就导致了你看到的崩溃信息。
如果你想把datalist里的所有字典元素追加到现有数组中,应该用addObjectsFromArray:方法;如果想直接替换整个数组,也要确保赋值的是可变数组:
正确代码示例
[manager POST:URL parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { // 方式1:替换整个数组(确保是可变数组) self.arrayDATA = [[responseObject objectForKey:@"datalist"] mutableCopy]; // 方式2:在现有数组基础上追加所有元素 // [self.arrayDATA addObjectsFromArray:[responseObject objectForKey:@"datalist"]]; [self.tableview reloadData]; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { // 别忘了处理请求失败的情况 }];
补充说明
之前[self setArrayDATA:[responseObject objectForKey:@"datalist"]]能正常运行,只是因为你没有调用可变数组的方法——但此时arrayDATA实际是不可变的NSArray,只是被你声明成了NSMutableArray,属于“类型不匹配的隐患”,如果后续你再调用addObject:还是会崩溃。
内容的提问来源于stack exchange,提问作者user2688045

