2

Я столкнулся с проблемой, о которой я понятия не имею, что пошло не так. У меня есть метод для сохранения информации в NSUserDefaults, а затем еще один способ ее получения. Но когда я получить это сообщение об ошибке пришел:iOS: кол-во объектов (0) отличается от количества ключей

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSDictionary initWithObjects:forKeys:]: count of objects (0) differs from count of keys (19)' 

Мой метод сбережение:

- (BOOL) grabAndSaveDataFromServerForPageCount: (int) pageCount 
{ 
NSData * serverResponse = [NSData dataWithContentsOfURL:[NSURL URLWithString:[self getFetchURLStringForPageType:FindLocate_Pet withInfo:[NSString stringWithFormat:@"%i",pageCount]]]]; 

if (![[NSJSONSerialization JSONObjectWithData:serverResponse options:kNilOptions error:nil] objectForKey:@"Count"]) 
{ 
    //Server Error. Jump over updating process. 
    serverResponse = nil; 
} 


if (serverResponse) 
{ 
    //We'll re-organize the data to be display-friendly 
    NSMutableDictionary * petsData = [NSJSONSerialization JSONObjectWithData:serverResponse options:kNilOptions error:nil]; 

    NSMutableDictionary * newDataToBeStored = [NSMutableDictionary dictionary]; 
    NSMutableArray * newGroupsOfIndividualPost = [NSMutableArray array]; 

    for (NSDictionary * individualPost in [petsData objectForKey:@"Content"]) 
    { 
     NSMutableDictionary * newIndividualPost = [individualPost mutableCopy]; 

     //"ID" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"ID"] forKey:@"ID"]; 

     //"TypeID" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"TypeID"] forKey:@"TypeID"]; 

     //"Name" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"Name"] forKey:@"Name"]; 

     //"GenderID" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"GenderID"] forKey:@"GenderID"]; 

     //"Description" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"Description"] forKey:@"Description"]; 

     //"PetsterTag" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"PetsterTag"] forKey:@"PetsterTag"]; 

     //"Color" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"Color"] forKey:@"Color"]; 

     //"Breed" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"Breed"] forKey:@"Breed"]; 

     //"BreedName" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"BreedName"] forKey:@"BreedName"]; 

     //"DOB" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"DOB"] forKey:@"DOB"]; 

     //"DateCreated" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"DateCreated"] forKey:@"DateCreated"]; 

     //"Lost" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"Lost"] forKey:@"Lost"]; 

     //"LostMessage" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"LostMessage"] forKey:@"LostMessage"]; 

     //"DateLost" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"DateLost"] forKey:@"DateLost"]; 

     //"ImageURLCover" 
     if ([(NSString *)[individualPost objectForKey:@"ImageURLCover"] length] > 0) 
     { 
      NSData * coverImageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:(NSString *)[individualPost objectForKey:@"ImageURLCover"]]]; 
      UIImage * coverImageConverted = [UIImage imageWithData:coverImageData]; 
      if (coverImageConverted) 
      { 
       [newIndividualPost setObject:coverImageConverted forKey:@"ImageURLCover"]; 
      } 
      else 
      { 
       [newIndividualPost setObject:[UIImage imageNamed:@"no_image.png"] forKey:@"ImageURLCover"]; 
      } 
     } 


     //"Die" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"Die"] forKey:@"Die"]; 

     //"DateDie" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"DateDie"] forKey:@"DateDie"]; 

     //"Enabled" 
     [newIndividualPost setObject:(NSString *)[individualPost objectForKey:@"Enabled"] forKey:@"Enabled"]; 



     //"MemberID" 
     NSDictionary * dataToWrite = [individualPost objectForKey:@"MemberID"]; 

     NSMutableDictionary * newIndividualMemberDetail = [NSMutableDictionary dictionary]; 


     //"ID" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"ID"] forKey:@"ID"]; 

     //"GenderID" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"GenderID"] forKey:@"GenderID"]; 

     //"ProfileImageURL" - Incomplete URL. Would save simply as NSString 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"ProfileImageURL"] forKey:@"ProfileImageURL"]; 

     //"Name" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"Name"] forKey:@"Name"]; 

     //"Company" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"Company"] forKey:@"Company"]; 

     //"DOB" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"DOB"] forKey:@"DOB"]; 

     //"NRIC" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"NRIC"] forKey:@"NRIC"]; 

     //"Passport" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"Passport"] forKey:@"NPassportRIC"]; 

     //"Nationality" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"Nationality"] forKey:@"Nationality"]; 

     //"Username" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"Username"] forKey:@"Username"]; 

     //"Password" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"Password"] forKey:@"Password"]; 

     //"PhoneNo" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"PhoneNo"] forKey:@"PhoneNo"]; 

     //"FaxNo" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"FaxNo"] forKey:@"FaxNo"]; 

     //"MobileNo" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"MobileNo"] forKey:@"MobileNo"]; 

     //"Email" 
     [newIndividualMemberDetail setObject:(NSString *)[dataToWrite objectForKey:@"Email"] forKey:@"Email"]; 

     //"ShowFields" group of data 
     NSString * jsonShowFields = [dataToWrite objectForKey:@"ShowFields"]; 

     NSString *jsonString = jsonShowFields; 
     NSData *dataShowFields = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; 
     NSDictionary * showFields = [NSJSONSerialization JSONObjectWithData:dataShowFields options:0 error:nil]; 

     //"isName" 
     if (![[showFields objectForKey:@"isName"] isKindOfClass:[NSNull class]]) 
     { 
      [newIndividualMemberDetail setObject:(NSString *)[showFields objectForKey:@"isName"] forKey:@"isName"]; 
     } 
     else 
     { 
      [newIndividualMemberDetail setObject:@"0" forKey:@"isName"]; 
     } 


     //"isAge" 
     if (![[showFields objectForKey:@"isAge"] isKindOfClass:[NSNull class]]) 
     { 
      [newIndividualMemberDetail setObject:(NSString *)[showFields objectForKey:@"isAge"] forKey:@"isAge"]; 
     } 
     else 
     { 
      [newIndividualMemberDetail setObject:@"0" forKey:@"isAge"]; 
     } 


     //"isMobileNo" 
     if (![[showFields objectForKey:@"isMobileNo"] isKindOfClass:[NSNull class]]) 
     { 
      [newIndividualMemberDetail setObject:(NSString *)[showFields objectForKey:@"isMobileNo"] forKey:@"isMobileNo"]; 
     } 
     else 
     { 
      [newIndividualMemberDetail setObject:@"0" forKey:@"isMobileNo"]; 
     } 

     //"isContactNo" 
     if (![[showFields objectForKey:@"isContactNo"] isKindOfClass:[NSNull class]]) 
     { 
      [newIndividualMemberDetail setObject:(NSString *)[showFields objectForKey:@"isContactNo"] forKey:@"isContactNo"]; 
     } 
     else 
     { 
      [newIndividualMemberDetail setObject:@"0" forKey:@"isContactNo"]; 
     } 

     //"isPhoneNo" 
     if (![[showFields objectForKey:@"isPhoneNo"] isKindOfClass:[NSNull class]]) 
     { 
      [newIndividualMemberDetail setObject:(NSString *)[showFields objectForKey:@"isPhoneNo"] forKey:@"isPhoneNo"]; 
     } 
     else 
     { 
      [newIndividualMemberDetail setObject:@"0" forKey:@"isPhoneNo"]; 
     } 



     //Final copy 
     [newIndividualPost setObject:newIndividualMemberDetail forKey:@"MemberID"]; 
     [newGroupsOfIndividualPost addObject:newIndividualPost]; 
    } 


    [newDataToBeStored setObject:newGroupsOfIndividualPost forKey:@"Content"]; 
    [newDataToBeStored setObject:[petsData objectForKey:@"Count"] forKey:@"Count"]; 

    if (pageCount>1) 
    { 
     //Means this info grab should add into the existing backup and not to replace it. 
     NSUserDefaults * storage = [NSUserDefaults standardUserDefaults]; 
     NSDictionary * existingData = (NSDictionary*) [NSKeyedUnarchiver unarchiveObjectWithData:[storage objectForKey:@"PetPageBackup"]]; 

     NSMutableDictionary * newExistingData = [existingData mutableCopy]; 
     [newExistingData addEntriesFromDictionary:newDataToBeStored]; 
     [storage setObject:[NSKeyedArchiver archivedDataWithRootObject:newExistingData] forKey:@"PetPageBackup"]; 

     [storage synchronize]; 

    } 
    else 
    { 

     //Directly save to NSUserDefaults by packaging it to a NSData format 
     NSUserDefaults * storage = [NSUserDefaults standardUserDefaults]; 
     [storage setObject:[NSKeyedArchiver archivedDataWithRootObject:newDataToBeStored] forKey:@"PetPageBackup"]; 

     [storage synchronize]; 
    } 

    return YES; 

} 
else 
{ 

    return NO; 
} 
} 

Мой метод при получении является:

NSUserDefaults * storage = [NSUserDefaults standardUserDefaults]; 
NSDictionary * petsData = (NSDictionary*) [NSKeyedUnarchiver unarchiveObjectWithData:[storage objectForKey:@"PetPageBackup"]]; 

И в последней строке где появилось предупреждение. Любая идея о том, почему это произошло?

Помощь!

EDIT:

Это состояние "newDataToBeStored" переменной перед сохранением в NSUserDefaults:

enter image description here

+0

Просьба показать полную трассировку стека. Вы говорите, что unarchiver вызывает ошибку? – Wain

+0

Да, последняя строка в коде выше, которую я попытался разблокировать сохраненные NSData, - это то место, где возникает ошибка. – Marcus

ответ

1

Попробуйте это,

newIndividualPost = [[NSMutableDictionary alloc]initWithDictionary: individualPost]; 

надеюсь, что это решит вашу проблему ,

1

Я думаю, что вы делаете простую ошибку, внутри цикла for вы создаете свой словарь, поскольку NSMutableDictionary * newIndividualPost = [individualPost mutableCopy]; означает, что вы не создаете новый новый объект, а создаете копию своего individualPost dictionary и снова вставляете те же объекты снова и снова. Поэтому замените свою линию NSMutableDictionary * newIndividualPost = [individualPost mutableCopy]; на NSMutableDictionary * newIndividualPost = [NSMutableDictionary new];, и она будет работать.

+0

'NSDictionary * d1 = @ {@" key ": @" value "}; NSMutableDictionary * d2 = [d1 mutableCopy]; d2 [@ "key"] = d1 [@ "key"]; 'Теперь' d2' * still * имеет один ключ и одно значение. Они перезаписываются. По существу, 'd2' после назначения является таким же, как и до назначения. Поэтому это не может быть причиной ошибки. – FreeNickname

+0

@iHulk Я попробовал ваше предложение, но по-прежнему появляется та же ошибка. – Marcus

+0

@FreeNickname, так что вы предлагаете? – Marcus

-2
//"ImageURLCover" 
if ([(NSString *)[individualPost objectForKey:@"ImageURLCover"] length] > 0) 
{ 
    NSData * coverImageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:(NSString *)[individualPost objectForKey:@"ImageURLCover"]]]; 
    UIImage * coverImageConverted = [UIImage imageWithData:coverImageData]; 
    if (coverImageConverted) 
{ 
    [newIndividualPost setObject:coverImageConverted forKey:@"ImageURLCover"]; 
} 
    else 
{ 
    [newIndividualPost setObject:[UIImage imageNamed:@"no_image.png"] forKey:@"ImageURLCover"]; 
} 
} 
+0

UIImage * coverImage = [UIImage imageWithCGImage: coverImageConverted.CGImage scale: coverImageConverted.scale orientation: coverImageConverted.imageOrientation]; – user5336298

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