mutating方法发送到不可变对象

时间:2014-03-19 07:30:41

标签: ios objective-c

有人可以告诉我为什么在第一次过去(或有时是第5次传递)这段代码有效。但是我随机收到崩溃的消息:

  

__ 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];
    }

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

的NSMutableArray

当我向数组添加对象时崩溃了。

修改

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

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];

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

我在iOS12上的NSMutableDictionary存在一个非常相似的问题。我可以使用dictionaryWithCapacity创建一个NSMutableDictionary,但是如果我使用

[[[NSMutableDictionary alloc] initWithContentsOfURL:[self urlForUnsentFilesDictionary] error:&writeError];

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

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

希望这对某人有帮助!