我是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