Эта строка неверна:
self.events = [[NSMutableArray array] autorelease];
Вы не должны там автоматически выпускать.Если не вызывать alloc / init и использовать метод класса, который возвращает объект, то по соглашению эти объекты возвращаются автоматически освобожденными.
Вы можете подумать, что повторное автоматическое его повторение предотвратит утечку, из-за которой объект слишком быстро освобождается из-за неравномерного высвобождения.Скорее всего, в то время как кажется, что это освобождение объекта, что-то еще, вероятно, сохранится и, вероятно, произойдет сбой позже.
Вот что происходит:
Авторелиз - это пул, который в основном говорит системе поставить очередь в очередь на потом.Читайте на NSAutoreleasePool.Обычно NSAutoreleasePool находится в верхней части основной петли в основной цепочке.
Другое дело, что функция массива будет возвращать автоматически выпущенную версию по соглашению.
Функция + (NSArray *)array
выглядит примерно так:
+ (NSArray *) array {
NSArray *ret = [[NSArray alloc] init];
return [ret autorelease];
}
Ваше свойствотакже имеет флаг "retain
", поэтому синтезированные методы выглядят примерно так:
- (NSArray *)events
{
return [[_events retain] autorelease];
}
- (void)setEvents:(NSArray *)anEvents
{
if (_events != anEvents) {
[_events autorelease];
_events = [anEvents retain];
}
}
Установщик здесь сохранит переданный массив.
Проблема в том, что выавтоматически освобождают объект, который уже был автоматически освобожден, а затем сохранен только еще 1 раз.У вас есть бальзамирование.
По существу, сохранение отсчета началось с 1 (как и все объекты, когда они выделяются), было запланировано для автоматического освобождения в два раза (что будет вычитать два удержания, когда пул сбрасывается в некоторыйточка в будущем), и она сохраняется один раз сеттером.К концу счет сохранения обнулится, и объект будет освобожден, когда вы этого не ожидаете.
в основном:
[NSMutableArray array]
... счетчик сохранения массива равен 1, авторелизы поставлены в очередь для вычитания 1 [array autorelease]
... счетчик хранения массива равенвсе еще 1, но теперь 2 авто-релиза поставлены в очередь, так что вычитайте 2 [self setEvents:...]
... массив сохраняется еще 1 раз, так что теперь счетчик равен 2, очередь автоматического выпуска все еще имеет его в очереди, чтобы вычесть 2 ... - (некоторое время спустя, когда вызывается
[NSAutoreleasePool drain/release]
, обычно с помощью насоса цикла событий) .. массивы освобождаются дважды, потому что ранее они были поставлены в очередь для автоматического выпуска дважды ... сохранить число равно 0. массив свободен.
Теперь что-то может сохранить ваш массив где-то в другом месте, поэтому он и остается.