1

I have a singleton class with a NSMutableArray property to which I want to add objects and remove objects. For some reason I am getting:

-[__NSDictionaryI setObject:forKey:]: unrecognized selector sent to instance 0x1edf24c0

exception when trying to add to it. Here is the relevant code for the interface of the singleton:

//outbox item is the type of objects to be held in the dictionary
@interface OutboxItem : NSObject
@property (nonatomic, assign) unsigned long long size;
@end

@interface GlobalData : NSObject
@property (nonatomic, copy) NSMutableDictionary *p_outbox;
+ (GlobalData*)sharedGlobalData;
@end

The implementation of the singleton:

@implementation GlobalData
@synthesize  p_outbox;
static GlobalData *sharedGlobalData = nil;
+ (GlobalData*)sharedGlobalData {
    if (sharedGlobalData == nil) {
        sharedGlobalData = [[super allocWithZone:NULL] init];
        sharedGlobalData.p_outbox = [[NSMutableDictionary alloc] init];
    }
    return sharedGlobalData;
}

+ (id)allocWithZone:(NSZone *)zone {
    @synchronized(self)
    {
        if (sharedGlobalData == nil)
        {
            sharedGlobalData = [super allocWithZone:zone];
            return sharedGlobalData;
        }
    }
    return nil;
}
- (id)copyWithZone:(NSZone *)zone {
    return self;
}
@end

And here is the code that throws the exception:

GlobalData* glblData=[GlobalData sharedGlobalData] ;
OutboxItem* oItem = [OutboxItem alloc];
oItem.size = ...;//some number here
[glblData.p_outbox setObject:oItem forKey:...];//some NSString for a key

Am I missing something very obvious??

4
  • 2
    The error indicates you have an immutable NSDictionary, not an NSMutableArray. Commented Mar 12, 2013 at 16:34
  • 1
    try @property (nonatomic, copy) NSMutableDictionary *p_outbox; making it to strong/retain Commented Mar 12, 2013 at 16:35
  • aha, yes, "copy" was the issue! Silly me. Commented Mar 12, 2013 at 16:37
  • The use of copy is fine if that is what you really want. But you need to see my answer to make it work properly. Commented Mar 12, 2013 at 16:39

2 Answers 2

3

The problem is with your property:

@property (nonatomic, copy) NSMutableDictionary *p_outbox;

The copy semantics of the property result in a copy of the dictionary being made when you assign a value to the property. But the copy method for a dictionary always returns an immutable NSDictionary, even when called on an NSMutableDictionary.

To solve this problem you must create your own setter method for the property:

// I'm a little unclear what the actual name of the method will be.
// It's unusual to use underscores in property names. CamelCase is the standard.
- (void)setP_outbox:(NSMutableDictionary *)dictionary {
    p_outbox = [dictionary mutableCopy];
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. I don't think I need copy, but your explanation is great.
2

Your

@property (nonatomic, copy) NSMutableDictionary *p_outbox;

is creating a copy of that object which you assign to it. As you are assigning a NSMutableDictionary to it, it's creates a copy of NSMutableDictionary object which is NSDictionary which is not a mutable copy.

So change it to

For Non ARC

@property (nonatomic, retain) NSMutableDictionary *p_outbox;

For ARC

@property (nonatomic, strong) NSMutableDictionary *p_outbox;

1 Comment

If you are using ARC, you must use strong instead of retain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.