Обновление словаря внутри массива из выбора строки в UITableView - PullRequest
0 голосов
/ 08 марта 2012

У меня есть массив словарей из фида JSON.Это заполняет UITableView.Когда пользователь выбирает строку, я использую UITableViewCellAccessoryCheckmark, и я пытаюсь изменить словарь внутри массива для этой строки, чтобы при повторном использовании ячейки после прокрутки она оставалась правильной.Однако я получаю ошибку.Вот мой код (сокращенно для ясности):

Метод данных JSON:

+ (NSMutableArray *)parseKennelData:(NSString *)type userID:(NSString *)user dogID:(NSString *)dog terms:(NSString *)terms
{
   NSURL *searchURL=[NSURL URLWithString:searchLocation];

   // download and parse the JSON
   NSData *JSONData = [[[NSData alloc] initWithContentsOfURL:searchURL] autorelease ];

   NSError *error=nil;
   CJSONDeserializer *deserializer = [CJSONDeserializer deserializer];
   NSMutableDictionary *JSONdictionary =[deserializer deserializeAsDictionary:JSONData error:&error]; 

   NSMutableArray *allResults = [JSONdictionary valueForKey:@"kennel"];

   return allResults;
}

Контроллер представления:

interface
{
    NSMutableArray *results;
}

- (void)viewDidLoad
{
    //  data for search
    self.results=[JSONData parseKennelData:@"search" userID:@"demo" dogID:@"" terms:self.terms];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    NSMutableDictionary *rowData = [self.results objectAtIndex:[indexPath row]];

    UITableViewCell *thisCell = [tableView cellForRowAtIndexPath:indexPath];

    if (thisCell.accessoryType == UITableViewCellAccessoryNone) 
    {        
        thisCell.accessoryType = UITableViewCellAccessoryCheckmark;
        thisCell.accessoryView = [[UIImageView alloc]
                          initWithImage:[UIImage imageNamed:@"tick-button.png"]]; 
        [rowData setObject:@"demo" forKey:@"user_id" ];        
    }
    else
    {
        thisCell.accessoryType = UITableViewCellAccessoryNone;  
        thisCell.accessoryView = [[UIImageView alloc]
                              initWithImage:[UIImage imageNamed:@"plusbutton.png"]];
        [rowData setObject:@"" forKey:@"user_id"];
    }

    [self.results replaceObjectAtIndex:[indexPath row] withObject:rowData];
}

Я получаю сообщение об ошибке SIGABRT:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'

Я думал, что я сделал все свои вещи изменяемыми, поэтому не вижу, где они падают.

Спасибо

1 Ответ

1 голос
/ 08 марта 2012

Вы говорите, что удостоверились, что все ваши вещи неизменны, но простое объявление указателей *JSONDictionary, *allResults и *rowData изменяемыми не делает их изменяемыми.Изменчивость этих объектов полностью зависит от правой части назначения.

Из полученной ошибки ясно, что словари, которые вы пытаетесь редактировать в didSelectRowAtIndexPath:, являются неизменяемыми.Кроме того, я не знаком с TouchJSON, но я почти уверен, что allResults также неизменен.

Чтобы исправить это, вам нужно внести два изменения, в обоих случаях используя удобный метод mutableCopy, чтобысделать изменчивую копию неизменяемого массива или словаря.Сначала создайте массив, возвращаемый parseKennelData:userID:dogID:terms: mutable:

NSMutableArray *allResults = [[JSONdictionary valueForKey:@"kennel"] mutableCopy];

А затем, в tableView:didSelectRowAtIndexPath:, сделайте изменяемую копию словаря перед его изменением:

NSMutableDictionary *rowData = [[self.results objectAtIndex:[indexPath row]] mutableCopy];
...