仅在iOS 9中,应用程序在[__NSCFDictionary setObject:forKey:]处崩溃



在验证空值时,崩溃

-[__NSCFDictionary setObject:forKey:]:发送给不可变对象的可变方法

当我使用所有可变类型时。(仅在iOS 9中崩溃,Appstore中我的应用程序的其他版本运行良好)

有人能建议我如何在为键设置值的null条件下处理这个问题吗。

 NSMutableArray *tempelementsArray=[[NSMutableArray alloc]init];
 if(![[catDic objectForKey:@"menuElementList"] isEqual:@""]){
                    tempelementsArray   =  [catDic objectForKey:@"menuElementList"];
    if(tempelementsArray != nil && [tempelementsArray count]>0)
      {
        for (NSInteger j=0; j<tempelementsArray.count; j++) {
        NSMutableDictionary *elementDic  = [[NSMutableDictionary alloc]init];
        elementDic = [tempelementsArray objectAtIndex:j];
       [elementDic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
    if ([obj isKindOfClass:[NSNull class]])
      {
        [elementDic setValue:@"" forKey:key];//App crashes here when one of the value is NULL
      }
     } ];
 }  

以下崩溃:

*** Terminating app due to uncaught exception NSInternalInconsistencyException', reason: '-[__NSCFDictionary  setObject:forKey:]: mutating method sent to immutable object'
*** First throw call stack:
(
0   CoreFoundation                      0x00df3a94 __exceptionPreprocess + 180
1   libobjc.A.dylib                     0x0051be02 objc_exception_throw + 50
2   CoreFoundation                      0x00df39bd +[NSException raise:format:] + 141
3   CoreFoundation                      0x00d0ed68 -[__NSCFDictionary setObject:forKey:] + 104
4   Foundation                          0x001051ba -[NSMutableDictionary(NSKeyValueCoding) setValue:forKey:] + 68
5   coreDataMenuSample                  0x000481d9 __33-[ViewController SaveToCoredata:]_block_invoke188 + 217
6   CoreFoundation                      0x00df2849 ____NSDictionaryEnumerate_block_invoke417 + 41
7   CoreFoundation                      0x00cd5452 CFBasicHashApply + 130
8   CoreFoundation                      0x00d12481 __NSDictionaryEnumerate + 273
9   CoreFoundation                      0x00d122ed -[NSDictionary enumerateKeysAndObjectsWithOptions:usingBlock:] + 45
10  CoreFoundation                      0x00d12235 -[NSDictionary enumerateKeysAndObjectsUsingBlock:] + 53
11  coreDataMenuSample                  0x00043e71 -[ViewController SaveToCoredata:] + 6481
12  coreDataMenuSample                  0x0004239d -[ViewController viewDidLoad] + 893
13  UIKit                               0x0133fd74 -[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 44
14  UIKit                               0x013448c2 -[UIViewController loadViewIfRequired] + 1556
)
libc++abi.dylib: terminating with uncaught exception of type NSException

我甚至检查过这个类似的问题。当将对象添加到可变数组时,出现了奇怪的"发送到不可变对象的变异方法"错误

保存CLLocation错误:发送到不可变对象的突变方法

看看你的代码,我认为问题出在这行上

NSMutableDictionary *elementDic  = [[NSMutableDictionary alloc]init];
        elementDic = [tempelementsArray objectAtIndex:j];

CCD_ 1包含CCD_ 2的实例而不是CCD_。更改此代码将有所帮助:

NSMutableDictionary *elementDic  = [[NSMutableDictionary alloc]initWithDictionary:tempelementsArray[j]];

您的代码有几个问题:

  • 首先,并不是因为你用可变对象初始化了一个变量,所以后续的初始化会转换为可变对象。所以当你这样做的时候:

    NSMutableDictionary *elementDic = [[NSMutableDictionary alloc]init]; elementDic = [tempelementsArray objectAtIndex:j];

    elementDic包含索引j处数组中的任何内容,因此在本例中可能是一个不可变对象。如果您希望对象是可变的,就必须使它们成为可变副本。

  • 其次,当你枚举字典时,你不能对它进行变异(这就是你在这里试图做的)。您必须制作一个可变副本,并在枚举原始副本时对副本进行变异。

  • 第三,如果您希望[catDic objectForKey:@"menuElementList"]是一个数组,为什么要测试它是否等于一个空字符串?!

以下是您代码的固定版本(使用现代obj-C语法,顺便说一句,它更容易阅读)

NSDictionary *catDic = ...
NSArray *tempElementsArray = catDic[@"menuElementList"];
NSMutableArray *mutableTempElementsArray = [NSMutableArray arrayWithCapacity:tempElementsArray.count];
if (![tempElementsArray isEqual:@""] && tempElementsArray != nil && tempElementsArray.count > 0)
{
    for (NSUInteger j = 0; j < tempElementsArray.count; j++)
    {
        NSDictionary *elementsDic  = tempElementsArray[j];
        NSMutableDictionary *mutableElementsDic = [NSMutableDictionary dictionaryWithCapacity:elementsDic.count];
        [elementsDic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
            if (obj == [NSNull null]) {
                obj = @"";
            }
            mutableElementsDic[key] = obj;
        }];
        [mutableTempElementsArray addObject:mutableElementsDic];
    }
}
NSMutableDictionary *mutableCatDic = [NSMutableDictionary dictionaryWithDictionary:catDic];
mutableCatDic[@"menuElementList"] = mutableTempElementsArray;

最新更新