0

I have a class that has a NSMutableDictionary as a property:

@interface Alibi : NSObject <NSCopying>
@property (nonatomic, copy) NSMutableDictionary * alibiDetails;
@end

With the following constructor:

- (Alibi *)init
{
    self = [super init];
    _alibiDetails = [NSMutableDictionary dictionary];
    return self;
}

and copy method:

- (Alibi *)copyWithZone:(NSZone *)zone
{
    Alibi *theCopy = [[Alibi alloc] init];
    theCopy.alibiDetails = [self.alibiDetails mutableCopy];    
    return theCopy;
}

When I try to call setObject:ForKey: I get a runtime error mutating method sent to immutable object.

I have the Alibi object declared in the view controller as @property (copy, nonatomic) Alibi * theAlibi; and I initialize it with self.theAlibi = [[Alibi alloc] init]; in viewDidLoad.

The line which crashes is:

NSString * recipient;
recipient = @"Boss";
[self.theAlibi.alibiDetails setObject:recipient forKey:@"Recipient"];

Please let me know what I am doing wrong here. I am coding for iOS 5 on iPhone.

Baruch
  • 1,133
  • 10
  • 18

2 Answers2

1

You have a 'copy' property, which means exactly that - your NSMutableDictionary will get the -copy method called and return a regular NSDictionary before being assigned to the synthesized instance variable. This thread provides some information on some of your options as to solving this.

Community
  • 1
  • 1
Carl Veazey
  • 18,392
  • 8
  • 66
  • 81
0

For the sake of completing this thread I will include my revised Alibi class below, this works as I require it to. If anyone notices any memory leaks or other issues, that would be appreciated.

@implementation Alibi

NSMutableDictionary *_details;

- (Alibi *)init
{
    self = [super init];
    _details = [NSMutableDictionary dictionary];
    return self;
}

- (NSMutableDictionary *)copyDetails
{
    return [_details mutableCopy];
}

- (NSMutableDictionary *)setDetails:(NSMutableDictionary *)value
{
    _details = value;
    return value;
}

- (void)addDetail:(id)value forKey:(id)key
{
    [_details setObject:value forKey:key];
}

- (id)getDetailForKey:(id)key
{
    return [_details objectForKey:key];
}

- (Alibi *)copyWithZone:(NSZone *)zone
{
    Alibi *theCopy = [[Alibi alloc] init];

    theCopy.serverId = [self.serverId copyWithZone:zone];
    theCopy.user = [self.user copyWithZone:zone];
    theCopy.startTime = [self.startTime copyWithZone:zone];
    theCopy.endTime = [self.endTime copyWithZone:zone];
    [theCopy setDetails:[self copyDetails]];

    return theCopy;
}

@end
Baruch
  • 1,133
  • 10
  • 18