NSDictionary: method only defined for abstract class. My app crashed

匿名 (未验证) 提交于 2019-12-03 01:47:02

问题:

My app crashed after I called addImageToQueue. I added initWithObjects: forKeys: count: but it doesn't helped me.

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

my code

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

回答1:

Are you subclassing NSDictionary? That's not a common thing to do in Cocoa-land, which might explain why you're not seeing the results you expect.

NSDictionary is a class cluster. That means that you never actually work with an instance of NSDictionary, but rather with one of its private subclasses. See Apple's description of a class cluster here. From that doc:

You create and interact with instances of the cluster just as you would any other class. Behind the scenes, though, when you create an instance of the public class, the class returns an object of the appropriate subclass based on the creation method that you invoke. (You don’t, and can’t, choose the actual class of the instance.)

What your error message is telling you is that if you want to subclass NSDictionary, you have to implement your own backend storage for it (for example by writing a hash table in C). It's not just asking you to declare that method, it's asking you to write it from scratch, handling the storage yourself. That's because subclassing a class cluster directly like that is the same as saying you want to provide a new implementation for how dictionaries work. As I'm sure you can tell, that's a significant task.

Assuming you definitely want to subclass NSDictionary, your best bet is to write your subclass to contain a normal NSMutableDictionary as a property, and use that to handle your storage. This tutorial shows you one way to do that. That's not actually that hard, you just need to pass the required methods through to your dictionary property.

You could also try using associative references, which "simulate the addition of object instance variables to an existing class". That way you could associate an NSNumber with your existing dictionary to represent the tag, and no subclassing is needed.

Of course, you could also just have tag as a key in the dictionary, and store the value inside it like any other dictionary key.



回答2:

From https://stackoverflow.com/a/1191351/467588, this is what I did to make a subclass of NSDictionary works. I just declare an NSDictionary as an instance variable of my class and add some more required methods. It's called "Composite Object" - thanks @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 


回答3:

I just did a little trick.
I'm not sure that its the best solution (or even it is good to do it).

@interface MyDictionary : NSDictionary  @end    @implementation MyDictionary  + (id) allocMyDictionary {     return [[self alloc] init]; }  - (id) init {     self = (MyDictionary *)[[NSDictionary alloc] init];      return self; }  @end 

This worked fine for me.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!