NSDictionary:仅为抽象类定义的方法。我的应用程序崩溃了

时间:2012-05-29 12:46:12

标签: ios crash nsdictionary

我调用addImageToQueue后,我的应用程序崩溃了。我添加了initWithObjects:forKeys:count:但它没有帮助我。

Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: '*** -[NSDictionary initWithObjects:forKeys:count:]: 
method only defined for abstract class.  
Define -[DictionaryWithTag initWithObjects:forKeys:count:]!'

我的代码

- (void)addImageToQueue:(NSDictionary *)dict
{
 DictionaryWithTag *dictTag = [DictionaryWithTag dictionaryWithDictionary:dict];
}

@interface DictionaryWithTag : NSDictionary
@property (nonatomic, assign) int tag;

- (id)initWithObjects:(id *)objects forKeys:(id *)keys count:(NSUInteger)count;

@end

@implementation DictionaryWithTag

@synthesize tag;

- (id)initWithObjects:(id *)objects forKeys:(id *)keys count:(NSUInteger)count
{
 return [super initWithObjects:objects forKeys:keys count:count];
}
@end

3 个答案:

答案 0 :(得分:42)

您是否继承NSDictionary?在Cocoa-land中这不常见,这可能解释了为什么你没有看到你期望的结果。

NSDictionary是一个类集群。这意味着你从来没有真正使用过NSDictionary的实例,而是使用它的一个私有子类。请参阅Apple对类集群here的描述。从那个文档:

  

您可以像创建任何其他类一样创建群集实例并与之交互。但是,在幕后,当您创建公共类的实例时,该类将根据您调用的创建方法返回相应子类的对象。 (您不能,也不能选择实例的实际类。)

您的错误消息告诉您的是,如果您想要子类化NSDictionary,则必须为其实现自己的后端存储(例如,通过在C中编写哈希表)。它不仅要求您声明该方法,还要求您从头开始编写,自己处理存储。这是因为直接对类集群进行子类化就像是说要为字典的工作方式提供新的实现。我相信你可以说,这是一项重大任务。

假设您肯定想要继承NSDictionary,最好的办法是编写子类以包含普通的NSMutableDictionary作为属性,并使用它来处理您的存储。 This tutorial向您展示了一种方法。实际上并不是那么难,你只需要将所需的方法传递给你的字典属性。

您也可以尝试使用associative references,它“模拟向现有类添加对象实例变量”。这样,您可以将NSNumber与现有字典相关联以表示标记,并且不需要子类化。

当然,您也可以将tag作为字典中的键,并将值存储在其中,就像任何其他字典键一样。

答案 1 :(得分:5)

https://stackoverflow.com/a/1191351/467588开始,这就是我为使NSDictionary的子类工作所做的工作。我只是将NSDictionary声明为我的类的实例变量,并添加一些更多必需的方法。它被称为"Composite Object" - 谢谢@mahboudz。

@interface MyCustomNSDictionary : NSDictionary {
    NSDictionary *_dict;
}
@end

@implementation MyCustomNSDictionary
- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt {
    _dict = [NSDictionary dictionaryWithObjects:objects forKeys:keys count:cnt];
    return self;
}
- (NSUInteger)count {
    return [_dict count];
}
- (id)objectForKey:(id)aKey {
    return [_dict objectForKey:aKey];
}
- (NSEnumerator *)keyEnumerator {
    return [_dict keyEnumerator];
}
@end

答案 2 :(得分:2)

我只是做了一个小技巧 我不确定它是最好的解决方案(甚至做得好)。

@interface MyDictionary : NSDictionary

@end  

@implementation MyDictionary

+ (id) allocMyDictionary
{
    return [[self alloc] init];
}

- (id) init
{
    self = (MyDictionary *)[[NSDictionary alloc] init];

    return self;
}

@end

这对我来说很好。