Утечка памяти, объекты в MutableArray не освобождаются? - PullRequest
2 голосов
/ 25 июля 2011

XCode сообщает мне, что с кодом ниже есть некоторые проблемы с точки зрения утечки памяти.

@property (nonatomic, retain) NSMutableArray *naw_rows;

-(void) loadTableRows:(BOOL)shouldReload
{
    [naw_rows removeAllObjects];

  [self.naw_rows addObject: [[CellModel alloc] initialize:@"name"     title:@"Name"          value: self.currentProfile.name]];
  [self.naw_rows addObject: [[CellModel alloc] initialize:@"company"  title:@"Company name"  value: self.currentProfile.company]];
  [self.naw_rows addObject: [[CellModel alloc] initialize:@"address"  title:@"Address"         value: self.currentProfile.address]];
  [self.naw_rows addObject: [[CellModel alloc] initialize:@"zipcode"  title:@"Zipcode"      value: self.currentProfile.zipcode]];
  [self.naw_rows addObject: [[CellModel alloc] initialize:@"city"     title:@"City"        value: self.currentProfile.city]];
}

// here is my cellModel object:
@implementation CellModel

-(id) initialize:(NSString *)newName title:(NSString *)newTitle value:(NSString *)newValue;
{
    if (self == [super init])
    {
        name = newName;
        title = newTitle;
        value = newValue;
    }
    return self;
}

- (NSString *) getName
{
   return name;
}

- (NSString *) getTitle
{
    return title;
}

- (NSString *) getValue
{
    return value;
}

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

@end;

Все строки addObject выдают следующую ошибку:

Потенциальная утечка объекта, размещенного в строке - метод возвращает Объект Objective-C со счетом удержания +1 (владеющий ссылкой) размещен на линии - не упоминается позже в этом пути выполнения и имеет счет удержания +1 (объект просочился)

В других темах об утечке памяти я обнаружил, что это будет правильный способ сделать это:

CellModel *model = [[CellModel alloc] initialize:@"name" title:@"Name" value: self.currentProfile.name];
[self.naw_rows addObject: model];
[model release];

Но это дает мне следующую ошибку:

Неверное уменьшение счетчика ссылок объекта, который не является принадлежит на данный момент вызывающему

Так что я делаю не так? В моем первом фрагменте кода счет сохранения должен быть 1. Принадлежит массиву. И я предполагаю, что объекты освобождаются, когда я использую [массив remodeAllObjects]

Заранее спасибо,

Nico

Ответы [ 2 ]

2 голосов
/ 25 июля 2011

Это утечки:

[self.naw_rows addObject: [[CellModel alloc] initialize:@"name"     title:@"Name"          value: self.currentProfile.name]];

Вы являетесь владельцем объекта, возвращаемого alloc-init, и вы несете ответственность за отказ от владения им, отправив ему сообщение release или autorelease, чего не смогли сделать.

Использование временной переменной, как вы предлагаете, решает проблему:

CellModel *model = [[CellModel alloc] initialize:@"name" title:@"Name" value: self.currentProfile.name];
[self.naw_rows addObject: model];
[model release];

Итак, почему анализатор жалуется? Из-за имени вашего инициализатора. Переименуйте его в что-то вроде initWithName:title:value:, и вы увидите, что «Неверное уменьшение счетчика ссылок на объект, который в данный момент не принадлежит вызывающей стороне» исчезнет.

Соглашение состоит в том, что имя методов инициализатора должно начинаться с сокращения init.

Кроме того, реализация вашего класса не присваивает self результат вызова инициализатора super. Это:

if (self == [super init])

должно быть:

if ((self = [super init]))

или, если вы предпочитаете:

self = [super init];
if (self)

Кроме того, управление памятью переменных экземпляра класса CellModel является неправильным. Вам следует сохранить или скопировать объекты, переданные в качестве аргументов, в метод init, а также освободить их в dealloc.

Методы доступа также нарушают соглашения об именах , они должны называться просто name, title и т. Д. Префикс "get" предназначен только для методов, которые возвращают объекты косвенно.

0 голосов
/ 25 июля 2011

Я считаю, что это потому, что CellModel владеет объектом.Хотя вы выпустили его, объект не имеет.Чтобы исправить это, добавьте код для освобождения массива в методе dealloc.

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

Кроме того, в качестве идентификатора обычно не следует полагаться на retainCount, поскольку он может легко вводить в заблуждение.

...