0

我有一個來自JSON提要的字典數組。這填充UITableView。當用戶選擇一行時,我使用UITableViewCellAccessoryCheckmark,並且我試圖修改該行內數組中的字典,因此當滾動後再次使用該單元格時它保持正確。但是,我收到一個錯誤。這裏是我的代碼(簡稱爲清楚起見):從UITableView中的行選擇更新數組中的字典

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' 

我thoug我確信所有的東西都是可變的,所以我看不出它在哪裏掉下來。

感謝

+1

你肯定** ** deserializeAsDictionary回報一個可變的字典? – 2012-03-08 17:57:06

回答

1

你說你確信你所有的東西不變,只是聲明你*JSONDictionary*allResults*rowData指針是可變的,並不能讓他們可變的。這些對象的可變性完全取決於作業的右側。

從您收到的錯誤中可以明顯看出,您試圖在didSelectRowAtIndexPath:中編輯的字典是不可變的。另外,我對TouchJSON並不熟悉,但我很肯定allResults也是不可變的。

要糾正這個問題,您需要進行兩項更改,在兩種情況下都使用方便的mutableCopy方法來創建不可變數組或字典的可變副本。

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

,然後在tableView:didSelectRowAtIndexPath:,修改之前使字典的可變副本:首先,該陣列由parseKennelData:userID:dogID:terms:可變返回

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

您應該製作mutableCopy以確保它被複制到可變對象,例如:NSMutableArray * allResults = [JSONdictionary valueForKey:@「kennel」] mutablCopy]; – 2012-03-08 19:26:20

+0

這還不夠:如果你這樣做'self.results'將是一個不可變字典的可變數組。 – yuji 2012-03-08 19:30:52

+1

我看到了這一點,我只是展示瞭如何輕鬆製作不可變對象的可變副本作爲示例。我不使用TouchJSON,所以我不能說數據是如何返回的。我應該說得更清楚。順便說一句,iOS5有一個新的JSON API,這使得這個東西更容易。感謝上帝,這已經過時了。感謝您的澄清,我不想混淆任何人,這是與所有有關的東西相反。 – 2012-03-08 19:57:05