Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSDictionary may not respond to setObject:forKey on a NSMutableDictionary object

I am new to Xcode and I am trying out this small program.

//  BookStoreMine.h
//  BookStore

#import <Cocoa/Cocoa.h>
#import "Book.h"

@interface BookStoreMine : NSObject {
NSDictionary* mybookStore;

}
@property (retain) NSDictionary* myBookStore;

-(id)init;
-(void)printInventory;
-(BOOL)addBook:(Book *)newBook;
-(BOOL)removeBookWithTitle:(NSString *)whichTitle;
-(void)dealloc;

@end

//  BookStoreMine.m
//  BookStore
#import "BookStoreMine.h"


@implementation BookStoreMine
@synthesize myBookStore;

-(id)init {
    self = [super init];
    if (self != nil) {
    myBookStore = [[NSMutableDictionary alloc] init];
}
return self;
}

-(BOOL)addBook:(Book *)newBook {
**[myBookStore setObject:newBook forKey:newBook.title];**
return YES;
}    

-(BOOL) removeBookWithTitle:(NSString *)whichTitle{
if ([myBookStore objectForKey:whichTitle] != nil) {
    **[myBookStore removeObjectForKey:whichTitle];**
    return YES;
}
return NO;
}

-(void)printInventory{
Book *book;
for (NSString* key in myBookStore) {
    book = [myBookStore objectForKey:key];
    NSLog(@" Title: %@",book.title);
    NSLog(@" Author: %@",book.author);
    NSLog(@" Description: %@",book.description);
    NSLog(@"ID is:%@",book.ID);
}
}

-(void)dealloc{
self.myBookStore = nil;
[super dealloc];
}

@end

I get warnings on the lines where I use setObject method on myBookStore and also when I use the removeObject method on the myBookStore object. The warning is "NSDictionary may not respond to setObject:forKey or removeObject:forKey. Why am I getting a warning related to NSDictionary when the object I am using is a NSMutableDictionary? How do I get rid of the warning? (PS: The program compiles and runs without any problem)

like image 435
Paul Rover Avatar asked Jul 11 '11 21:07

Paul Rover


3 Answers

At runtime you are setting the myBookStore object to be an instance of NSMutableDictionary.

At compile time, it's still declared as an NSDictionary, which doesn't respond to the messages for set or remove.

If you declare the variable as an NSMutableDictionary, the warnings will go away.

like image 72
highlycaffeinated Avatar answered Oct 23 '22 19:10

highlycaffeinated


Change these two lines:

NSDictionary* mybookStore;

@property (retain) NSDictionary* myBookStore;

to look like this:

NSMutableDictionary* mybookStore;

@property (retain) NSMutableDictionary* myBookStore;

Xcode is looking at the declarations of ivars when determining what methods they implement, and if you should always declare ivars as what they are going to be be.

like image 33
theMikeSwan Avatar answered Oct 23 '22 19:10

theMikeSwan


You've declared mybookStore as an NSDictionary. The compiler therefore believes it to be an NSDictionary. The fact that an NSMutableDictionary is assigned to it at runtime doesn't alter that.

Probably you want to change the declaration within your @interface to an NSMutableDictionary (though it still makes sense to return it as immutable in your @property, as you don't want external actors to think they have the right to modify it).

like image 4
Tommy Avatar answered Oct 23 '22 17:10

Tommy