Рассмотрим NSSet
. Он имеет назначенный инициализатор:
- (id)initWithObjects:(const id *)objects count:(NSUInteger)cnt {
// initialization code here
return self;
}
У него также есть несколько вторичных инициализаторов, например этот:
- (id)initWithArray:(NSArray *)array {
NSUInteger count = array.count;
id objects[count];
[array getObjects:objects range:NSMakeRange(0, count)];
return [self initWithObjects:objects count:count];
}
Теперь вам нужен подкласс NSSet
, который автоматически отклоняет строку «Боб». Таким образом, вы должным образом переопределяете назначенный инициализатор в своем подклассе, но вызываете один из вторичных инициализаторов super:
@implementation BobRejectingSet
- (id)initWithObjects:(const id *)objects count:(NSUInteger)count {
NSMutableArray *array = [[NSMutableArray alloc] initWithCount:count];
for (NSUInteger i = 0; i < count; ++i) {
if (![objects[i] isEqual:@"Bob"]) {
[array addObject:objects[i]];
}
}
return [super initWithArray:array];
}
Что происходит, когда вы делаете это:
BobRejectingSet *noBobs = [[BobRejectingSet alloc] initWithArray:someObjects];
Поскольку вы не переопределили initWithArray:
, программа вызывает -[NSSet initWithArray:]
, который вызывает назначенный инициализатор initWithObjects:count:
. Вы переопределили назначенный инициализатор, поэтому он вызывает ваш метод. Ваш метод отфильтровывает Bobs, а затем вызывает вторичный инициализатор super, initWithArray:
…, который разворачивается и снова вызывает указанный вами переопределенный инициализатор. Неограниченная рекурсия. Переполнение стека. Вы получаете блюз нарушения сегментации ядра.
Вот почему вы всегда используете назначенный супер инициализатор.
person
rob mayoff
schedule
07.04.2012