[英]Objective-C IOS Xcode: Unable to modify object in NSMutableArray
My problem is that I have a class property that is of type NSMutableArray
, as defined in my header file, yet when I attempt to modify one of the array elements (an NSDictionary
) I receive the following runtime error: 我的问题是,我的头文件中定义了一个具有
NSMutableArray
类型的类属性,但是当我尝试修改其中一个数组元素( NSDictionary
)时,却收到以下运行时错误:
2013-01-16 14:17:20.993 debtaculous[5674:c07] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray replaceObjectAtIndex:withObject:]: mutating method sent to immutable object'
2013-01-16 14:17:20.993 bondaculous [5674:c07] *由于未捕获的异常“ NSInternalInconsistencyException”而终止应用程序,原因:“-[__ NSCFArray replaceObjectAtIndex:withObject:]:发送给不可变对象的变异方法”
Header declaration: 标头声明:
// BudgetViewController.h
#import <UIKit/UIKit.h>
@interface BudgetViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
- (IBAction)afterTaxIncomeEditingDidEnd:(id)sender;
@property (strong, nonatomic) NSMutableArray *budgetArray;
@property (strong, nonatomic) IBOutlet UITextField *afterTaxIncome;
@property (strong, nonatomic) IBOutlet UITableView *budgetTableView;
@end
Method that generates the error: 产生错误的方法:
-(void)applyCCCSWeights
{
NSMutableDictionary *valueDict;
NSString *newAmount;
for (id budgetElement in [self budgetArray]) {
valueDict = [[NSMutableDictionary alloc] initWithDictionary:budgetElement];
newAmount = [NSString stringWithFormat:@"%0.2f", [[self afterTaxIncome].text floatValue] * [[budgetElement objectForKey:@"cccs_weight"] floatValue]];
[valueDict setValue:newAmount forKeyPath:@"amount"];
[[self budgetArray] replaceObjectAtIndex:0 withObject:valueDict];
NSLog(@"%0.2f (%0.2f)", [[budgetElement objectForKey:@"amount"] floatValue], [[self afterTaxIncome].text floatValue] * [[budgetElement objectForKey:@"cccs_weight"] floatValue]);
}
[self.budgetTableView reloadData];
}
// Note the replaceObjectAtIndex:0
above is just a placeholder. //请注意,上面的
replaceObjectAtIndex:0
只是一个占位符。 This will be replaced with the correct index. 这将被替换为正确的索引。
budgetArray
is surely immutable, you have to create it mutable. budgetArray
当然是不可变的,您必须将其创建为可变的。
Probably you're doing something like this: 可能您正在执行以下操作:
budgetArray= [NSArray arraWithObjects; obj1, obj2, nil];
And ignoring the compiler warning. 并忽略编译器警告。 Make it mutable:
使它可变:
budgetArray= [[NSMutableArray alloc]init];
I'm fairly certain you cannot change a mutable object during enumeration. 我相当确定您无法在枚举期间更改可变对象。
This SO question may help: Setting an object during fast enumeration problems 这样的问题可能会有所帮助: 在快速枚举问题期间设置对象
In your init method, put this: 在您的init方法中,输入以下内容:
budgetArray = [[NSMutableArray alloc] init];
Also, why not use dictionary and array literal syntax? 另外,为什么不使用字典和数组文字语法呢?
-(void)applyCCCSWeights {
NSMutableDictionary *valueDict;
NSString *newAmount;
for (NSDictionary *budgetElement in [self budgetArray]) {
valueDict = [budgetElement mutableCopy];
newAmount = [NSString stringWithFormat:@"%0.2f", [[self afterTaxIncome].text floatValue] * [budgetElement[@"cccs_weight"] floatValue]];
valueDict[@"amount"] = newAmount;
_budgetArray[0] = valueDict;
NSLog(@"%0.2f (%0.2f)", [budgetElement[@"amount"] floatValue], [[self afterTaxIncome].text floatValue] * [budgetElement[@"cccs_weight"] floatValue]);
}
[self.budgetTableView reloadData];
}
Notice that [[self budgetArray] replaceObjectAtIndex:0 withObject:valueDict];
注意,
[[self budgetArray] replaceObjectAtIndex:0 withObject:valueDict];
becomes: _budgetArray[0] = valueDict;
变为:
_budgetArray[0] = valueDict;
You can't change an array while doing a fast iteration over the array. 在数组上进行快速迭代时,不能更改数组。 On the other hand, it's entirely unnecessary;
另一方面,这完全没有必要。 the code is absolutely inefficient: Just make the elements of the array NSMutableDictionaries, then change the dictionaries directly, instead of creating a copy and then changing an element in the copy.
代码是绝对无效的:仅使数组NSMutableDictionaries的元素,然后直接更改字典,而不是创建副本然后更改副本中的元素。
Noticed later that you use NSJSONSerialization; 稍后会注意到您使用NSJSONSerialization; look at the flags and don't pass 0 blindly.
查看标志,不要盲目传递0。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.