NSDictionary可能不会响应NSMutableDictionary对象上的setObject:forKey



我是Xcode的新手,我正在试用这个小程序。

//  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

当我在myBookStore上使用setObject方法以及在myBookStore对象上使用removeObject方法时,我会得到警告。警告是"NSDictionary可能不会响应setObject:forKey或removeObject:forKey"。当我使用的对象是NSMutableDictionary时,为什么我得到一个与NSDictionary相关的警告?我如何摆脱警告?(PS:程序编译和运行没有任何问题)

运行时myBookStore对象设置为NSMutableDictionary的实例。

编译时,它仍然被声明为NSDictionary,它不响应set或remove消息。

如果将变量声明为NSMutableDictionary,则警告将消失。

修改这两行:

NSDictionary* mybookStore;
@property (retain) NSDictionary* myBookStore;

看起来像这样:

NSMutableDictionary* mybookStore;
@property (retain) NSMutableDictionary* myBookStore;

Xcode在决定ivars实现什么方法时,会查看它的声明,如果你应该总是声明ivars,

您已经将mybookStore声明为NSDictionary。因此编译器认为它是一个NSDictionary。NSMutableDictionary在运行时被赋值的事实并没有改变它。

可能你想改变你的@interface中的声明到NSMutableDictionary(尽管它仍然是有意义的返回它作为不可变的在你的@property,因为你不希望外部参与者认为他们有权利修改它)。

看起来您的意图是给您的类的用户一个immutable NSDictionary,这样他们就不能修改您在内部使用的ivar。根据你声明了这个方法的事实判断

-(void)printInventory;

我猜你的类的真正用户根本不需要看到NSDictionary变量。如果是这种情况,那么我通常做的是不声明我将在头文件内部使用的ivar。这样做的效果是让我的类的用户使用提供的getter/setter,并且我可以随时更改内部数据结构。要实现这一点,您需要使用类扩展来添加额外的ivar。

这会使你的类看起来像这样——注意你的头文件(公共API)看起来干净多了:

//  BookStoreMine.h
//  BookStore
#import <Cocoa/Cocoa.h>
#import "Book.h"
@interface BookStoreMine : NSObject
- (void)printInventory;
- (BOOL)addBook:(Book *)newBook;
- (BOOL)removeBookWithTitle:(NSString *)whichTitle;
@end
//  BookStoreMine.m
//  BookStore
#import "BookStoreMine.h"
@interface BookStoreMine ()
@property (retain) NSMutableDictionary* myBookStore;
@end
@implementation BookStoreMine
@synthesize myBookStore;
- (id)init 
{
    self = [super init];
    if (self != nil) {
      myBookStore = [[NSMutableDictionary alloc] init];
    }
    return self;
}
- (BOOL)addBook:(Book *)newBook 
{
  [self.myBookStore setObject:newBook forKey:newBook.title];
  return YES;
}    
- (BOOL)removeBookWithTitle:(NSString *)whichTitle 
{
  if ([myBookStore objectForKey:whichTitle] != nil) {
    [self.myBookStore removeObjectForKey:whichTitle];
    return YES;
  }
  return NO;
}
- (void)printInventory
{
  Book *book;
  for (NSString* key in self.myBookStore) {
    book = [myBookStore objectForKey:key];
    NSLog(@" Title: %@",book.title);
    NSLog(@" Author: %@",book.author);
    NSLog(@" Description: %@",book.description);
    NSLog(@"ID is:%@",book.ID);
  }
}
- (void)dealloc
{
  [myBookStore release];
  [super dealloc];
}
@end

最新更新