在IOS

2012-02-12 44 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]; 
} 

有幾點:

1日。正如你看到的,屬性「myData」是保留的,所以我認爲每一個我爲它設置了一個對象,它會自動保留該對象?

2nd。每當視圖出現時,我必須重新加載「myData」,就像上面第1行的代碼一樣。

3rd。由於它是保留財產,我必須正確地釋放它。

現在,問題是,我是否正確地管理了內存,沒有使用上面的代碼泄漏「myData」?

如果視圖會多次出現之前,它是dealloc的,(如推動在一個UINavigationController進一步查看和彈出幾次),

然後myData的會保留一些反對不止一次,但我只能在dealloc中釋放它,並在第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; 

如此通過分配任何東西(包括nil)你已經調用release隱含擴大到

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

。因爲您沒有任何明確的retain,您實際上可以將第2行替換爲self.myData = nil;以決不會調用release

+2

請注意,如果代碼按照您的建議工作,則'self.property = self.property'會導致對象可能被釋放。它實際上在'objc_release'之前調用'objc_retain',參見['objc_setProperty_non_gc'](http://www.opensource.apple.com/source/objc4/objc4-493.9/runtime/Accessors.subproj/objc-accessors.m) – 2012-02-12 04:08:02

+0

謝謝大家,我開始理解它,所以即使是保留也是在發佈前,我以前的代碼纔是正確的,對吧? – 2012-02-12 16:23:15

+0

@SedateAlien是的,我應該補充說,沒有改變的特殊情況並不通過這條路線,但是這與上述情況無關。這只是這個概念的一個例證。 – 2012-02-12 16:27:51

0

.H

@property (nonatomic, retain) NSArray *myData; 

.M

@synthesize myData; 

通過在你的這幾行代碼一個setter和getter是你的財產MYDATA的創建。在運行時爲對象生成的setter看起來像這樣,

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

總的效果是,只要你在之前附加自你實際上是調用getter和setter方法訪問屬性。所以下面兩行是完全一樣的。

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

所以你原來的代碼已經是正確的。