2012-10-10 32 views
2

試圖繞過某些iOS設備上發生的崩潰,並結合Apple提供的建議「不會導致分配峯值」。我怎樣才能改變這個代碼不會一次發生?iOS - 一次不分配太多內存

for (Item *item in self.items) { 
     ItemView *itemView = [[ItemView alloc] initWithFrame:CGRectMake(xPos, kYItemOffsetIphone, kItemWidthIphone, kItemHeightIphone) ]; 

     itemView.delegate = self; 
     [itemView layoutWithData:item]; //this just adds an imageView and button 
     [self.scrollView addSubview:itemView]; 
     xPos += kXItemSpacingIphone; 
    } 

self.items數組中有大約20個對象,用於構建20個ItemView。再一次,有沒有辦法讓這個代碼更「分配密集」?

+2

是否所有的視圖可以同時顯示?如果沒有,你可以推遲創建一個視圖直到它將要在屏幕上顯示(同樣,當它離開屏幕時你可以銷燬一個視圖[只要你稍後可以重新創建它的當前狀態])。這是'UITableView'的工作原理。 –

+0

@KevinBallard是否有UIScrollView的樣板代碼? – soleil

+1

@soleil所以你基本上想要的是一個'UITableView'但旋轉了90度? – Tommy

回答

1

我親手做的線沿線的東西:

  1. 讓我的視圖控制器滾動視圖的delegate(如果你這樣做的代碼,你必須修改視圖控制器的.h說它符合UIScrollViewDelegate)。 (a)確定滾動視圖的可見部分的框;以及(b)確定滾動視圖的可見部分的框。 (b)確定哪個子視圖與該可見部分相交; (c)加載可見的項目,並卸載那些不可見的項目。

因此,例如,它可能看起來像下面這樣:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    // Determine the frame of the visible portion of the scrollview. 

    CGRect visibleScrollViewFrame = scrollView.bounds; 
    visibleScrollViewFrame.origin = scrollView.contentOffset; 

    // Now iterate through the various items, remove the ones that are not visible, 
    // and show the ones that are. 

    for (Item *itemObject in self.itemCollection) 
    { 
     // Determine the frame within the scrollview that the object does (or 
     // should) occupy. 

     CGRect itemObjectFrame = [self getItemObjectFrame:itemObject]; 

     // see if those two frames intersect 

     if (CGRectIntersectsRect(visibleScrollViewFrame, itemObjectFrame)) 
     { 
      // If it's visible, then load it (if it's not already). 
      // Personally, I have my object have a boolean property that 
      // tells me whether it's loaded or not. You can do this any 
      // way you want. 

      if (!itemObject.loaded) 
       [itemObject loadItem]; 
     } 
     else 
     { 
      // If not, go ahead and unload it (if it's loaded) to conserve memory. 

      if (itemObject.loaded) 
       [itemObject unloadItem]; 
     } 
    } 
} 

這是基本的想法。您當然可以根據您的應用程序的特定設計來優化此邏輯,但這是我通常如何做到的。

+1

很好的回答。提交者也可能實現某種可重用的視圖數組,這樣當項目被移出屏幕時,它們將從視圖層次結構中移除並添加到此可重用視圖數組中。在加載新項目時,代碼可以檢查是否存在已創建的可重用視圖,如果是,則獲取對可重用視圖的引用,然後將其從陣列中移除。沖洗並重復。這與'UITableView'的實例如何在包含很多視圖的非常長的列表中管理其單元格非常相似。 –

+1

@ThuggishNuggets同意。我試圖保持簡單,但你說得很對。 (這種出列邏輯可能屬於這些'loadItem'和'unloadItem'方法。)爲了獲得最佳性能,他可能還想對圖像進行一些緩存(我將NSCache的子類)。在滾動視圖結束時它會很煩人,並且會在圖像重新獲取時稍微延遲一段時間。但是,我仍然試圖保持簡單。 – Rob