在做相册Demo的时候,想通过NSUserDefaults来保存Demo程序多个(4个)相册组中相片的增删修改,于是在相册主页面通过NSUserDefaults单例来加载数据源:
先声明一个可变数组作为相片的数据源:
/这里从NSUserDefaults里面加载数据源/
_dataSource = [[NSUserDefaults standardUserDefaults] objectForKey:@"imageDataSource"];
/**初次加载如果_dataSource为空,则从plist文件加载**/
if (_dataSource.count == 0) {
// 此处第一次加载数据源的响应操作
}
[[NSUserDefaults standardUserDefaults] setObject:_dataSource forKey:@"imageDataSource"];//第一次加载时把plist里面读取的数据源数组同步到NSUserDefaults单例里面
}
[_tableView reloadData];
}
在第三级相册详情页面,删除某张照片,用以下方法:
[_detailAlbumDataSource removeObjectAtIndex:XX_Index];
程序却崩溃了,提示mutating method sent to immutable object。明明声明的是可变数组,为何删除元素的时候却提示对不可变数组运用了可变数组的方法?
仔细分析发现,从首页加载数据源开始,首页的数据源数组_dataSource
指针指向了NSUserDefaults单例对象所在内存空间,在详情页传值传过来的照片详情数组_detailAlbumDataSource
数据引用了数据源数组的指针,同样也指向了NSUserDefaults单例对象。
我们知道,单例对象是创建于内存的数据段,而不是像NSMutableArray一样在堆空间开辟的内存空间,因此用NSMutableArray的方法去删除元素程序就崩溃了。
解决办法:重新创建一个临时可变数组,通过临时数组来增删,再与_detailAlbumDataSource
替换:
NSMutableArray * tmpArray = [NSMutableArray arrayWithArray:_detailAlbumDataSource];
[tmpArray removeObjectAtIndex:_deleteTag];
总结:**出现mutating method sent to immutable object的原因有可能是你的可变数组指针引用了单例对应的指针,而单例是存在于内存数据段的,不能进行增删改操作。
**解决办法:
(1)创建一个临时数组进行数据交换;
(2)可变数组先在内存堆空间开辟一个空间,再传入NSUserDefaults单例传过来的值。