2012-02-12 4 views
1

Там есть немного редкость ситуация в моем приложении, то есть,Смешение об управлении памятью на IOS

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

код выглядит это:

// .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]; 
} 

есть несколько точек:

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

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

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

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

Если представление будет появляться много раз, прежде чем dealloc, (как толчок в дальнейшем зрении в 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]; 
} 

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

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

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

ответ

1

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

self.myData = anything; 

расширяется до

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

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

+2

Обратите внимание, что если код работал так, как вы предлагаете, 'self.property = self.property' приведет к тому, что объект может быть освобожден. Он фактически вызывает 'objc_retain' перед' objc_release', см. ['Objc_setProperty_non_gc'] (http://www.opensource.apple.com/source/objc4/objc4-493.9/runtime/Accessors.subproj/objc-accessors.m) –

+0

Спасибо, ребята, я начинаю понимать это, поэтому даже сохранение до выпуска, мой прежний код будет правильным, не так ли? –

+0

@SedateAlien Да, и я должен был добавить, что особый случай без изменений не проходит через этот маршрут, но это не относится к делу выше. Это была всего лишь иллюстрация концепции. –

0

.h

@property (nonatomic, retain) NSArray *myData; 

.m

@synthesize myData; 

Включив эти строки в коде и присваиватель создаются для вашего имущества MyData.Сеттер генерируется во время выполнения для объектов выглядит примерно так,

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

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

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

Так что вы сделали правильный выбор.

Смежные вопросы