发送到不可变对象的变异方法

Posted

技术标签:

【中文标题】发送到不可变对象的变异方法【英文标题】:mutating method sent to immutable object 【发布时间】:2014-03-19 07:30:40 【问题描述】:

谁能告诉我为什么在第一次过去(或者有时是第五次通过)这段代码有效。但是,我随机崩溃并显示以下消息:

__NSCFArray insertObject:atIndex:]:变异方法发送到不可变对象'

代码如下:

if (![self.recentSearchesArray containsObject:self.filterParameters[@"includedKeywords"]])

        [self.recentSearchesArray addObject:[self.filterParameters [@"includedKeywords"] mutableCopy]];
        [[NSUserDefaults standardUserDefaults]setObject:[self.recentSearchesArray mutableCopy] forKey:@"RecentSearches"];
        [self.SavedSearchesTableView reloadData];
    

最近搜索的数组是一个 NSMutableArray,声明为 @property(strong, nonotomic)NSMutableArray *recentSearchesArray

当我向数组中添加一个对象时它崩溃了。

编辑

我最近的搜索数组是这样分配的:

if (!self.recentSearchesArray)
        self.recentSearchesArray = [NSMutableArray array];
    

我的过滤参数字典是这样分配的:

    self.filterParameters = [NSMutableDictionary dictionaryWithDictionary:params];

params 是这样分配的 NSDictionary:

NSDictionary *params = [NSDictionary dictionaryWithObject:self.searchTerm forKey:@"includedKeywords"];

解决方案

根据标记的答案 - NSUserDefaults 是问题:

self.recentSearchesArray = [[NSUserDefaults standardUserDefaults]objectForKey:@"RecentSearches"];

这返回了一个 NSArray 而不是 NSMutableArray。我从没想过 NSUserDefaults 就是这种情况。

这是返回可变副本的正确方法

    self.recentSearchesArray = [[[NSUserDefaults standardUserDefaults]objectForKey:@"RecentSearches"] mutableCopy];

【问题讨论】:

你的 recentSearchesArray 是指可变实例吗? 是的 - 字典是可变的。 self.filteredParameters 数组还是字典?你是怎么分配的? 编辑了问题以显示分配情况。 【参考方案1】:

检查您设置recentSearchArray 变量的位置。也许您将其设置为NSArray 的对象。 还要检查从NSUserDefaults 获取此数组的代码,因为NSUserDefaults 将返回class NSArray 的对象。

【讨论】:

哦,我不知道。这是我使用 NSUserDefaults self.recentSearchesArray = [[NSUserDefaults standardUserDefaults]objectForKey:@"RecentSearches"]; 中的旧数据填充数组的方法 这是 NSUserDefaults 返回一个 NSArray 而不是可变副本。谢谢!。【参考方案2】:

我在 ios12 上遇到了与 NSMutableDictionary 非常相似的问题。我可以使用dictionaryWithCapacity 创建一个NSMutableDictionary,但如果我回忆起一个使用

[[NSMutableDictionary alloc] initWithContentsOfURL: [self urlForUnsentFilesDictionary] 错误:&writeError];

当我后来尝试向其中添加对象时,我会收到该错误。在 iOS13 上运行良好。我最终通过在 initWithContentsOfURL 之后添加它来修复它:

dict = CFBridgingRelease(CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (__bridge CFDictionaryRef)dict, kCFPropertyListMutableContainersAndLeaves));

希望这对某人有所帮助!

【讨论】:

以上是关于发送到不可变对象的变异方法的主要内容,如果未能解决你的问题,请参考以下文章

崩溃:发送到不可变对象的变异方法

发送到不可变对象的变异方法 - iOS [重复]

尽管对象是 NSMutableDictionary,但“发送到不可变对象的变异方法”

使用 NSMutableArray 将变异方法发送到不可变对象

发送到不可变对象的变异方法

使用 userInfo (null) 发送到不可变对象的变异方法