Как создать типизированный стек с помощью Objective-C - PullRequest
1 голос
/ 10 марта 2011

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

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

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

Ответы [ 3 ]

3 голосов
/ 10 марта 2011

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

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

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

2 голосов
/ 10 марта 2011

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

@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
1 голос
/ 10 марта 2011

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

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

...