0
votes

I'm attempting to add an accessory (checked/unchecked) to this tableview, and for some reason xCode is telling me that something is wrong with this line: [item setObject:cell forKey:@"StrainTableCell"];

The console throws me this error:

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

Does anyone know why? See code snippets below.

ViewController.h

#import <UIKit/UIKit.h>
#import "PickerViewController.h"


@interface PickerResultsTableViewController : UITableViewController  {

    NSIndexPath *currentDetailPath;
    bool loaded;


    NSArray *Strains;
    NSArray *searchResults;
    NSMutableArray *dataArray;
    NSMutableData *data;

}

- (IBAction)backbuttonpressed: (UIBarButtonItem *)sender;

@property (strong, nonatomic) NSArray *favoritesArrayset;
@property (strong, nonatomic) IBOutlet UITableView *PickerTableView;
@property (nonatomic, retain) NSArray *searchResults;
@property (nonatomic, strong) NSMutableSet * favoritesArray;

@end

ViewController.m

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    static NSString *strainTableIdentifier = @"StrainTableCell";

    StrainTableCell *cell = (StrainTableCell *)[tableView dequeueReusableCellWithIdentifier:strainTableIdentifier];
    if (cell == nil)


        cell = [[StrainTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strainTableIdentifier];

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.selectionStyle = UITableViewCellSelectionStyleBlue;


    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"StrainTableCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];



        if (tableView == PickerTableView) {
            NSLog(@"Using the search results");

            cell.titleLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Title"];
            cell.descriptionLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Description"];
            cell.ratingLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Rating"];
            cell.ailmentLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Ailment"];
            cell.actionLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Action"];
            cell.ingestLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Ingestion"];

            NSLog(@"%@", searchResults);



        } else {
            NSLog(@"Using the FULL LIST!!");
            cell.titleLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Title"];
            cell.descriptionLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Description"];
            cell.ratingLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Rating"];
            cell.ailmentLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Ailment"];
            cell.actionLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Action"];
            cell.ingestLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Ingestion"];

        }


    NSMutableDictionary *item = [Strains objectAtIndex:indexPath.row];
    cell.textLabel.text = [item objectForKey:@"text"];

    [item setObject:cell forKey:@"StrainTableCell"];
    BOOL checked = [[item objectForKey:@"checked"] boolValue];

    NSLog(@"%i",checked);
    UIImage *image = (checked) ? [UIImage   imageNamed:@"checked.png"] : [UIImage imageNamed:@"unchecked.png"];
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
    button.frame = frame;
    [button setBackgroundImage:image forState:UIControlStateNormal];
    [button addTarget:self action:@selector(checkButtonTapped:event:)  forControlEvents:UIControlEventTouchUpInside];
    button.backgroundColor = [UIColor clearColor];
    cell.accessoryView = button;

    return cell;

}
1
Why are you adding a cell to the dictionary in the first place? Since cells get recycled, I think this is probably not a good idea.rdelmar

1 Answers

0
votes

Well, the compiler is giving you a pretty good hint about what's going on: mutating method sent to immutable object. Even though you're declaring item as a NSMutableDictionary it doesn't mean that the object you're getting from [Strains objectAtIndex:indexPath.row] is in fact a mutable dictionary.

Even if you do something like this:

NSDictionary *dict1 = [[NSDictionary alloc] init];

//the following line does not convert dict1 into a mutable dictionary
NSMutableDictionary *dict2 = (NSMutableDictionary*)dict1;

To solve this issue make sure the objects you add to Strains are mutable dictionaries. You could do this by directly instantiating one or by calling the mutableCopy method.

Hope this helps!