Как создать типизированный стек с помощью 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 и т. Д., И следуйте их указаниям.