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

发布于 2024-11-19 16:06:28 字数 1516 浏览 0 评论 0原文

我是 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:程序编译运行没有任何问题)

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

岁吢 2024-11-26 16:06:29

您已将 mybookStore 声明为 NSDictionary。因此,编译器认为它是一个 NSDictionary。事实上,在运行时为它分配 NSMutableDictionary 并不会改变这一点。

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

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).

埖埖迣鎅 2024-11-26 16:06:29

看来您的意图是为您的类的用户提供一个immutable NSDictionary,这样他们就无法修改您在内部使用的ivar。从你声明了这个方法的事实来看,

-(void)printInventory;

我猜你的类的用户实际上根本不需要看到 NSDictionary ivar。如果是这种情况,那么我通常所做的就是根本不声明我将在头文件中内部使用的 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

It would appear that your intention is to give the user of your class an immutable NSDictionary so they cannot modify the ivar you are using internally. Judging by the fact you have this method declared

-(void)printInventory;

I would guess that really the user of your class does not need to see the NSDictionary ivar at all. If this is the case then what I normally do is not declare the ivar that I will use internally in the header file at all. This has the effect of making the user of my class use the getters/setters provided and I can change the internal data structure anytime I want. To achieve this you will need to use a class extension to add the additional ivar.

This will make your class look like this - notice how much cleaner your header file (public API) looks:

//  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
南城追梦 2024-11-26 16:06:28

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

编译时,它仍然被声明为NSDictionary,它不会响应设置或删除的消息。

如果您将变量声明为 NSMutableDictionary,警告就会消失。

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.

吹泡泡o 2024-11-26 16:06:28

将这两行更改为:

NSDictionary* mybookStore;

@property (retain) NSDictionary* myBookStore;

看起来像这样:

NSMutableDictionary* mybookStore;

@property (retain) NSMutableDictionary* myBookStore;

Xcode 在确定它们实现什么方法时会查看 ivars 的声明,以及您是否应该始终将 ivars 声明为它们将要成为的样子。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文