2010-06-17 46 views
1

在我的應用程序工作流程中的各個點上,我需要顯示一個視圖。該視圖內存密集,因此我希望它在被用戶丟棄時被釋放。所以,我寫了下面的代碼:可可內存管理

- (MyView *)myView { 
    if (myView != nil) 
     return myView; 

    myView = [[UIView alloc] initWithFrame:CGRectZero]; // allocate memory if necessary. 
    // further init here 

    return myView; 
} 

- (void)discardView { 
    [myView discard]; // the discard methods puts the view offscreen. 
    [myView release]; // free memory! 
} 

- (void)showView { 
    view = [self myView]; 
    // more code that puts the view onscreen. 
} 

不幸的是,這種方法只能在第一次使用。後續請求將屏幕放在屏幕上導致"message sent to deallocated instance"錯誤。顯然,釋放的實例與nil不同。我想在[myView release]之後放置一條額外的行,該行的內容爲myView = nil。但是,這可能會導致錯誤(在該行之後調用myView可能會產生錯誤)。

那麼,我該如何解決這個問題呢?

+0

如果您在發佈myView後正在調用myView,那麼*要*會產生錯誤。 – walkytalky 2010-06-17 17:35:52

回答

4

myView設置爲nil是正確的事情在這裏做。 不是這樣做是什麼產生錯誤,因爲它無法檢測地指向一個釋放對象。您的代碼測試nil以查看是否需要創建新視圖,因此應該適當地設置該變量。

1

您將會遇到問題,因爲您不使用訪問器。您需要爲視圖定義一個屬性。然後,每當你參考視圖使用自我點符號。如果你這樣做,然後簡單地設置視圖屬性爲這樣的零:

self.myView=nil; 

...將自動觸發其釋放。

但是,這是管理視圖的不好的方法,特別是如果從nib加載它的話。該視圖很可能是控制器對象的必需屬性。將其設置爲零會導致崩潰。

更好的辦法是讓視圖控制器處理內存問題。在iPhone上,您可以將內存管理代碼放入viewDidDisappear:didReceiveMemoryWarning。無論如何,只要控制器處於活動狀態,您就不會終止視圖,而是釋放視圖的內存密集部分,例如圖片。這使得視圖成爲一個輕量級的shell對象。然後在'viewWillAppear`中加載內存密集的部分。

但是,處理這個問題的最好方法是從導航堆棧中實際彈出視圖控制器。此時視圖控制器自動清理完畢。