2015-10-27 4 views
1

9 при проверке нулевых значений, то происходит сбой сприложение падает на [__NSCFDictionary SetObject: forKey:] в прошивкой только

- [__ NSCFDictionary SetObject: forKey]: метод мутирует отправлен неизменного объекта

Когда я использую все изменяемого тип. (сбой только прошивка 9, другие версии моего приложения в Appstore работает отлично)

Может кто-нибудь предложить мне, как справиться с этим при нулевом состоянии в SETV alue для ключа.

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 

Я даже проверил эту аналогичный вопрос Strange “mutating method sent to immutable object” error when adding an object to a mutable array

Saving CLLocation error: Mutating method sent to immutable object

+0

Я не уверен, почему вы получаете это исключение, но вы не должен мутировать словарь во время его перечисления. Мое подозрение состоит в том, что enumerateKeysAndObjectsUsingBlock делает словарь неизменным временно, чтобы защитить его во время перечисления. – Paulw11

ответ

4

Посмотрите на свой код, я думаю, что проблема эта линия

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

tempelementsArray содержит экземпляр NSDictionary вместо NSMutableDictionary. Изменения в этот код поможет:

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

Я собирался прокомментировать что-то подобное. Кроме того, вы считаете, что значение в tempelements [i] подходит для входа в словарь.Это может быть что угодно: сначала получите этот объект на отдельной строке кода, проверьте его «isKindOfClass» класса, который вы хотите (т.е. словарь), и только затем установите его в словаре. –

+0

@ LukeSmith спасибо ..Вертификация сейчас .. – Sujania

+1

Не забудьте скопировать этот новый словарь обратно по старой ... – trojanfoe

1

Есть несколько вещей неправильно с вашим кодом:

  • Во-первых, это не потому, что вы инициализирует переменную с изменяемым объектом, что последующие инициализацый будут преобразованы в изменчивый объекты. Так что, когда вы делаете:

    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; 
+0

это приводит к сбою моего приложения с «Завершающим приложением из-за неперехваченного исключения» NSInternalInconsistencyException », причина: '- [__ NSCFArray insertObject: atIndex:]: метод мутации, отправленный в неизменяемый объект' в строке -" [tempelementsArray addObject: mutableElementsDic]; " – Sujania

+0

Вы скопировали мой код или переписали его? Вы должны использовать' mutableTempElementsArray' в этой строке, а не 'tempElementsArray'. Модифицированная версия вашего массива будет находиться в' mutableTempElementsArray'. – deadbeef

+0

Что делает 'tempElementsArray isEqual: @" 'even mean? – trojanfoe

Смежные вопросы