Анализатор отмечает потенциальную утечку для этой конструкции

С помощью следующего кода анализатор помечает вызов селектора setMyDict как потенциальную утечку, а в процессе освобождения он сообщает: «Некорректное уменьшение счетчика ссылок на данный момент не принадлежит вызывающей стороне».

- (id)init {
  if (self = [super init]) {
      [self setMyDict:[[NSMutableDictionary alloc] init]];
  }
  return self;
}

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

@synthesize myDict = _myDict;

Я не понимаю этого. Я думал, что с помощью alloc init объект увеличивает счетчик удержания на единицу, а указатель сохраняется в _myDict через синтезируемое свойство. Если я использую этот код вместо

- (id)init {
  if (self = [super init]) {
    _myDict = [[NSMutableDictionary alloc] init];
  }
  return self;
}

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

Анализатор не жалуется. Что мне не хватает?


person maxbareis    schedule 06.03.2010    source источник


Ответы (1)


@Synthesize предоставляет вам сеттер и получатель для объекта, который вы синтезируете.

Метод установки выглядит примерно так (взято из документации Apple)

-(void)setMyDict:(NSMutableDictionary *)newDict {
    if (myDict != newDict) {
       [myDict release];
       myDict = [newDict retain];
    }
}

Вы создаете утечку, когда делаете:

[self setMyDict:[[NSMutableDictionary alloc] init]];

Потому что вы никогда не освобождаете только что выделенный словарь.

Способ обойти это:

NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];
[self setMyDict:dict];
[dict release];

Это устранит утечку.

В методе dealloc следует использовать:

[myDict release]; // Or whatever your property is called.
person Tom Irving    schedule 06.03.2010
comment
Я бы добавил, что вам никогда не следует использовать форму ссылки метода в dealloc.Таким образом, никогда не используйте self.propertyName из [self getPropertyName] для выпуска. Это вызывает методы, которые могут иметь непредсказуемые результаты, если ваши средства доступа более сложные. - person TechZen; 06.03.2010
comment
Или просто используйте [self setMyDict: [NSMutableDictionary dictionary]] - person Stefan Arentz; 06.03.2010
comment
Вдохновленный вашими действительно хорошими комментариями, я прочитал гораздо больше об объявлениях свойств и нашел динамическое объявление ivars 64-разрядной средой выполнения. К сожалению, их нельзя использовать с iPhone-Simulator. Но если кто-то хочет сократить последующие переделки, когда эта функция доступна для Simulator, следует использовать следующее: in init: [self setMyDict: [NSMutableDictionary dictionary]] в dealloc: [self setMyDict: nil] - person maxbareis; 07.03.2010