Подтвердить что ты не робот

Почему мой подкласс NSMutableArray работает так, как ожидалось?

Я подклассифицировал NSMutableArray следующим образом:

Базовый класс:

@interface MyBaseMutableArray : NSMutableArray {
    // Database variables
    NSString * databaseName;
    NSString * databasePath;
}

@property (nonatomic, retain) NSString * databasePath;

- (id)initWithContentsOfSQLiteDB:(NSString *)dbTable;
-(void) checkAndCreateDatabase;
-(void) readFromDatabase;

@end

Подкласс:

@interface IngredientsMutableArray : MyBaseMutableArray
{

}

-(void) readFromDatabase;

@end

Когда я создаю IngredientsMutableArray, я делаю следующее:

IngredientsMutableArray * i  = [[IngredientsMutableArray alloc]
    initWithContentsOfSQLiteDB:@"MyIngredientsDB.sql"];

НО, когда я пытаюсь выполнить [self addObject: component], я делаю исключение следующим образом:

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

Я считаю, что я не инициализирую NSMutableArray правильно. Я собирался для нас initWithCapaciity, но я не знаю счет перед вызовом SQL. Я думаю, что я пропускаю что-то очевидное, но, будучи новичком в Objective C, я немного озадачен.

Любая помощь приветствуется.

4b9b3361

Ответ 1

В соответствии с документацией вам необходимо:

Методы переопределения

Методы NSMutableArray: концептуально основанных на этих примитивных Методы:

insertObject:atIndex:

removeObjectAtIndex:

addObject:

removeLastObject

replaceObjectAtIndex:withObject:

В подклассе вы должны переопределить все эти методы, хотя вы можете реализовать требуемую функциональность используя только первые два (однако это вероятно, будет неэффективным). Вы должны также переопределяют примитивные методы класс NSArray.

Но реальный ответ заключается в том, что вы действительно не хотите быть подклассом. Существует два варианта:

  • Используйте категорию
  • Создайте новый класс с NSArray как переменную-член

Я думаю, что в этом случае я бы выбрал вариант 2.

В общем, вы склонны подклассифицировать системные классы гораздо реже, чем на С# или Java.

Ответ 2

Вы не хотите подклассифицировать NSArray или NSMutableArray. Это кластер классов. Из Документы NSArray:

Любой подкласс NSArray должен переопределить методы примитивных экземпляров подсчитываются и objectAtIndex:. Эти методы должны работайте в резервном магазине, который вы предусматривают элементы коллекция. Для этого магазина поддержки вы может использовать статический массив, стандартный Объект NSArray или некоторые другие данные типа или механизма. Вы также можете выбрать частично или полностью переопределить любые другой метод NSArray, для которого вы хочу предоставить альтернативу реализация.

Как рекомендуется в тех же документах, попробуйте категорию или состав, а не наследование.

Ответ 3

NSMutableArray является кластером - класс NSMutableArray определяет интерфейс и когда вы его создаете, вы получаете объект другой, частный тип. Это делает NSMutableArray и кластеры других классов сложными для подкласса, вам будет намного лучше с составом. Прочтите эту Friday Q & A с Mike Ash, если вы заинтересованы в деталях [gory].