Сообщения «Неверный декремент» и «Потенциальная утечка» от анализатора - PullRequest
0 голосов
/ 26 октября 2011

Когда я компилирую с анализатором, я получаю пару сообщений.У меня объявлены следующие свойства:

@property (nonatomic, retain) SyncServicePrimary *syncAndCartOne;
@property (nonatomic, retain) SyncServiceSecondary *syncAndCartTwo;

Этот метод вызывается из applicationDidBecomeActive, и я получаю «Потенциальную утечку выделенного объекта».

-(void)makeTheCartObjectsForCountry:(NSString*)country_key{
    self.syncAndCartOne = [[SyncServicePrimary alloc] init];
    self.syncAndCartTwo = [[SyncServiceSecondary alloc] init];
}

Это вызывается в applicationWillResignActive;здесь я получаю «Неверное уменьшение счетчика ссылок объекта».

-(void) removeTheCartObjects{
    [self.syncAndCartOne release];
    self.syncAndCartOne = Nil;    
    [self.syncAndCartTwo release];
    self.syncAndCartTwo = Nil; 
}

Если я установлю объекты на autorelease, ошибка исчезнет, ​​но я хочу, чтобы объекты были освобождены, когда приложениепрячется.

Это то, что я делаю правильно, но это слишком далеко, чтобы анализатор мог видеть начало и конец, или это то, что я могу сделать лучше / правильно, чтобы он не жаловался?

Более чем вероятно, что я упускаю простую концепцию в отношении циклов release и alloc (я пришел из PHP и C #).

Ответы [ 2 ]

4 голосов
/ 26 октября 2011

Ваша проблема здесь:

-(void)makeTheCartObjectsForCountry:(NSString*)country_key{
    self.syncAndCartOne = [[SyncServicePrimary alloc] init];
    self.syncAndCartTwo = [[SyncServiceSecondary alloc] init];
}

Вы создаете объекты и затем сохраняете их (из-за объявления свойства), поэтому они имеют счетчик ссылок 2, когда ссылается только один объектих.

Вы должны сделать это так:

-(void)makeTheCartObjectsForCountry:(NSString*)country_key{
    SyncServicePrimary *primary = [[SyncServicePrimary alloc] init];
    self.syncAndCartOne = primary;
    [primary release];

    SyncServiceSecondary *secondary = [[SyncServiceSecondary alloc] init];
    self.syncAndCartTwo = secondary;
    [secondary release];
}
2 голосов
/ 26 октября 2011

Вы определили свойства с атрибутом retain, поэтому анализатор предполагает, что метод установки для свойства выглядит следующим образом:

- (void)setSyncAndCartOne:(SyncServicePrimary *)newValue
{
    [newValue retain];
    [self->_syncAndCartOne release]; // access the instance variable holding the property value
    self->_syncAndCartOne = newValue;
}

Если вы используете @synthesize, метод установки будет выглядетьвот так.

Итак, когда makeTheCartObjectsForCountry: возвращается, объект в syncAndCartOne имеет счет сохранения 2, но должен иметь счет сохранения только 1. Поэтому использование autorelease исправляет его.

Вы не должны делать [self.syncAndCartOne release] по той же причине.Метод setter отправит старый объект release, когда вы назначите nil свойству.

...