Смущает управление памятью на IOS - PullRequest
1 голос
/ 12 февраля 2012

В моем приложении есть немного необычная ситуация, то есть

Я должен перезагружать некоторые сохраняемые свойства каждый раз, когда должно появиться представление,

код выглядит следующим образом:

// .h
@property (nonatomic, retain) NSArray *myData;
// .m
@synthesize myData;
- (void)viewWillAppear:(BOOL)animated {
    ... // get FetchRequest and so on
    self.myData = [self.context executeFetchRequest:request error:&error]; // Line 1
[super viewWillAppear:animated];
}
- (void)viewDidUnload {
    self.myData = nil;
    [super viewDidUnload];
}
- (void)dealloc {
    [myData release];  // Line 2
    [super dealloc];
}

Есть несколько пунктов:

1-й.Как вы видите, свойство "myData" сохраняется, поэтому я думаю, что каждый раз, когда я устанавливаю для него какой-либо объект, он автоматически сохраняет этот объект?

2nd.Я должен перезагружать «myData» каждый раз, когда появится представление, как и код строки 1. выше.

3-ий.Поскольку это свойство сохранения, я должен сам его правильно освободить.

Теперь вопрос в том, правильно ли я управлял памятью без утечки myData, используя приведенные выше коды?

Если представление будет отображаться много раз, прежде чем оно будет освобождено (как, например, нажатие в дополнительном представлении в UINavigationController и его появление несколько раз),

, тогда myData сохранит некоторый объект более одного раза, но я освобождаюэто в dealloc для 1 раз в строке 2, так что это нормально?

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

- (void)viewWillDisappear:(BOOL)animated {
    self.myData = nil;
    [myData release];
[super viewWillDisappear:animated];
}
- (void)dealloc {
 //   [myData release];  // don't release it here.
    [super dealloc];
}

мое приложение зависнет после того, как один или два раза я нажму и выскользну из представления,

Так, какое из них действительно неправильное?

Большое спасибо!

Ответы [ 2 ]

1 голос
/ 12 февраля 2012

Вы выпускаете его не только в строке 2, но и в строке 1, когда он заменяется, а также в viewDidUnload, так что ваш код сверху просто в порядке.Ключ в том, что

self.myData = anything;

расширен до

[self->myData release];
self->myData = [anything retain];

, поэтому, присваивая что-либо (включая nil), вы уже неявно вызываете release.На самом деле вы можете заменить строку 2 на self.myData = nil;, чтобы никогда не вызывать release, поскольку у вас нет явного retain.

0 голосов
/ 12 февраля 2012

.h

@property (nonatomic, retain) NSArray *myData;

.m

@synthesize myData;

Путем включения этих строк в ваш код создается и получается метод для вашего свойства myData.Сеттер, сгенерированный во время выполнения для объектов, выглядит примерно так:

- (void)setMyData: (id)newValue
{
    if (myData != newValue)
    {
        [myData release];
        myData = newValue;
        [myData retain];
    }
}

Общий эффект состоит в том, что всякий раз, когда вы обращаетесь к свойству, добавляя self впереди, вы фактически вызываете сеттеры и геттеры.Таким образом, следующие две строки абсолютно одинаковы.

self.myData = nil;
[self setMyData:nil];

Итак, ваш исходный код был уже верным.

...