2013-05-01 63 views
1

我正在通過我的iOS應用程序,使用「模擬內存警告」作爲我的正義之錘,並且它引起了一些意想不到的問題(自然而然)。但是這是一個讓我難以接受的問題:對象似乎不再平等。didReceiveMemoryWarning和重新構建的實例變量相等性檢查

說我的視圖控制器(我們將其命名爲VCBob)有...

  • 兩個單獨定製UIViews爲子視圖(讓我們命名這些觀點viewAviewB
    • 每個都有自己的UICollectionView暴露物業collectionView(這些UICollectionViews使用VCBob作爲他們delegates
  • 一個UIButton在按下時,上到堆棧

所以我輕觸UIButton和這裏推一些其他視圖控制器(否則微不足道的一個)來了微不足道視圖控制器。我點燃了「模擬內存警告」選項,並且VCBob被編程爲在-didReceiveMemoryWarning內部丟棄viewAviewB,因爲它們被完全重新創建並重新插入到viewWillAppear的視圖層次結構中(只要它們是nil時間爲viewWillAppear)。下面是VCBob該實現:

- (void)didReceiveMemoryWarning { 
    BOOL hasSuperview = self.view.superview != nil; 
    [super didReceiveMemoryWarning]; 

    if (!hasSuperview) { 
     _viewA = nil; 
     _viewB = nil; 
    } 
} 

我然後點擊導航欄上的後退按鈕,並VCBob回來發揮作用。這兩個自定義UIViews仍然存在,並且它們各自的UICollectionViews都加載了內容。當我在任一集合視圖中點擊其中一個UICollectionViewCells時,將在VCBob上調用-collectionView:didSelectItemAtIndexPath:方法;到現在爲止還挺好。這個實現看起來像這樣。

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { 
    if (collectionView == self.viewA.collectionView) { 
     NSLog(@"Do something here!"); 
    } else if (collectionView == self.viewB.collectionView) { 
     NSLog(@"Do something else here!"); 
    } 
} 

問題是沒有任何反應 - 沒有得到記錄。這兩個if條件評估爲false。這是爲什麼?我似乎認爲我可能會在didReceiveMemoryWarning中做壞事。我不應該在那裏處理意見嗎?

回答

1

如果_viewA是在一個視圖層次,它是由它的父保留,這樣做_viewA = nil不會釋放它,它依然存在,當viewWillAppear方法被炒魷魚。

然後,在您的viewWillAppear中,您正在添加一個viewA的「重複」,其中有自己的collectionView,放在原來的一個上面:您看到一個視圖,但實際上它們是兩個視圖重疊。

所以,你應該在你的didReceiveMemoryWarning方法添加removeFromSuperview呼籲擺脫這種

同樣的情況,爲viewB

+0

你得出了我所做的確切結論,並在發佈我的報告後發佈了一個瞬間。但既然你不是我,我會給你答案的功勞! – 2013-05-01 20:18:06

+0

阿哈哈謝謝:)用英文寫作需要我太多時間,我必須仔細檢查每一個單詞我鍵入..如果我可以在意大利回答我會更快:) – 2013-05-01 20:20:43

+0

我想如果我可以閱讀意大利語,我也會是一個更好的人。謝謝,亞歷山德羅! (順便說一下,你的英語很好。) – 2013-05-01 20:32:36

0

大鼠,我想我想通了。我在didReceiveMemoryWarning中處理了我的觀點,而沒有先從超級視角中移除它們。我所在的UIView顯然仍然保留着我的陳舊物品的實例,儘管我已將它們排除在外。

- (void)didReceiveMemoryWarning { 
    BOOL hasSuperview = self.view.superview != nil; 
    [super didReceiveMemoryWarning]; 

    if (!hasSuperview) { 
     [_viewA removeFromSuperview]; 
     _viewA = nil; 
     [_viewB removeFromSuperview]; 
     _viewB = nil; 
    } 
}