Не работает подкласс NSDictionary

#objective-c #cocoa-touch #ios #nsdictionary

#objective-c #cocoa-touch #iOS #nsdictionary

Вопрос:

У меня есть словарь, который я прочитал из списка. Я хочу создать подкласс NSDictionary для реализации чего-то вроде следующего, чтобы я мог избежать использования @"key name" везде в моем исходном коде:

 @interface MyDict{
}
-(NSString*) textString;
@end

@implementation MyDict
-(NSString*) textString {
    return [self objectForKey:@"textString"];
}
@end
  

В моем другом методе:

 MyDict *d = ... // something i read from plist
NSString *str = [d textString];
  

Когда я вызываю метод, приложение завершает работу из-за «нераспознанной текстовой строки селектора». Что здесь не так?

Комментарии:

1. Это ваш точный код? Ваш @interface действительно такой? Или это @interface MyDict:NSDictionary {

Ответ №1:

Простое присвоение NSDictionary указателю MyDict не делает его экземпляром MyDict.

Одним из способов сделать это было бы создать категорию, чтобы добавить ваш метод в NSDictionary. Смотрите http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocCategories.html#//apple_ref/doc/uid/TP30001163-CH20-SW1 для информации.

Комментарии:

1. 1 подкласс NSDictionary — плохая идея, но категория была бы более подходящим способом сделать это.

2. Кстати — NSDictionary может не быть фактическим экземпляром класса NSDictionary — это забавно. Вместо этого добавьте категорию в NSDictionary.

3. Категория на самом деле не является подходящим решением. Вы будете добавлять этот универсальный метод к каждому экземпляру словаря в приложении. Почти наверняка, существует лучший шаблон проектирования для использования.

Ответ №2:

У вашего класса нет суперкласса. Кроме того, общепринятое мнение заключается в том, что его очень сложно подклассифицировать, NSDictionary потому что это кластер классов. На самом деле вы не получаете NSDictionary ответ, когда вы:

 NSDictionary * myDict = [NSDictionary dictionary];
  

Вы получаете частный подкласс ( NSCFDictionary в данном случае).

Возможно, вы захотите попробовать определить свои собственные ключи словаря, как это делает Apple:

 NSString * const MyWonderfulUnicornKey = @"MyWonderfulUnicornKey";
  

Комментарии:

1. Я думаю, проще и, возможно, безопаснее использовать глобальную переменную. Мое желание — просто избежать опечатки и повысить удобство обслуживания. Однако, как я могу использовать общий заголовочный файл для объявления этого? У меня есть много файлов, использующих его. Но если я просто импортирую common .H, компилятор будет жаловаться на повторное объявление, даже когда я вставляю его в блок #ifndef XXXX #endif

2. Поместите import и #ifndef в файл .pch вашего проекта, для этого он и существует, насколько я понимаю.