Как создать типизированный стек с помощью Objective-C

Однако я могу довольно легко создать класс стека, используя методы доступа push и pop для NSArray. Я могу сделать это универсальным для любого производного класса NSObject, однако я хочу хранить только определенный класс в этом стеке.

В идеале я хочу создать что-то похожее на типизированные списки Java (List или List), чтобы я мог хранить только этот тип в стеке. Я могу создать разные классы для каждого (ProjectStack или ItemStack), но это приведет к более сложной файловой структуре.

Есть ли способ сделать это, чтобы ограничить тип класса, который я могу добавить в контейнер, к определенному настраиваемому типу?

3 ответа

Решение

Вы можете попробовать что-то вроде этого, хотя я не рекомендую это:

@interface TypedMutableStack : NSObject {
   Class type;
@private
   NSMutableArray *internal;
}

- (id) initWithType:(Class) type_;

@end

#define CHECK_TYPE(obj) if(![obj isKindOfClass:type]) {\
      [NSException raise:NSInvalidArgumentException format:@"Incorrect type passed to TypedMutableStack"];\
 }


@implementation TypedMutableStack

- (void) dealloc {
  [internal release];
  [super dealloc];
}

- (id) initWithType:(Class) type_ {
   self = [super init];
   if(self) {
      type = type_;
      internal = [[NSMutableArray alloc] init];
   }
   return self;
}

- (void) addObject:(id) obj {
   CHECK_TYPE(obj);
   [internal addObject:obj];
}

- (void) replaceObjectAtIndex:(NSUInteger) index withObject:(id) obj {
    CHECK_TYPE(obj);
    [internal replaceObjectAtIndex:index withObject:obj];
}

- (void) insertObject:(id) obj atIndex:(NSUInteger) index {
    CHECK_TYPE(obj);
    [internal insertObject:obj atIndex:index];
}

//...
@end

NSArray будет принимать любой объект, который реализует тот же протокол, что и NSObject; это не должно быть получено из NSObject. Поскольку вся диспетчеризация в Objective-C является динамической, наследование не требуется для полиморфизма.

Если оставить в стороне, если вы реализовали свои собственные методы push и pop, вы можете легко протестировать входящий тип, используя isKindOfClass или isMemberOfClass, и отклонить неправильный тип.

Чтобы пойти дальше, NSMutableArray документирует, какие методы являются концептуально примитивными, под заголовком "Примечания по подклассам" в разделе "Обзор" в верхней части страницы. Если вы создадите подкласс NSMutableArray и измените addObject:, replaceObjectAtIndex:withObject: и insertObject:atIndex: для проверки типа входящего объекта, то вы можете создать типизированный массив.

Objective-C не имеет шаблонов или шаблонов. Следовательно, идиоматический код Objective-C написан с использованием NSObject * а также id везде кастинг по необходимости.

Что бы вы ни хотели сделать, вы должны смоделировать это на существующих платформах. Посмотрите, как реализованы NSArray, NSDictionary, NSSet и т. Д., И следуйте их указаниям.

Другие вопросы по тегам