2010-11-30 11 views
1

ScrollViewSuiteに問題があります。必要以上のメモリを使用します。例えば :ScrollViewSuiteサンプルコードは必要以上のメモリを使用しますか?

  1. ロード画像25%およびメモリ(4 MB)100%まで画像で
  2. ズームを測定し、メモリ(30メガバイト)を測定
  3. ズームを25%に出て、メモリを測定します( 30 MB) - なぜ30?それは4 MBだけを使用しなければなりません - それが問題です。

この問題を解決するにはどうすればよいですか?

/***********************************************************************************/ 
/* Most of the work of tiling is done in layoutSubviews, which we override here. */ 
/* We recycle the tiles that are no longer in the visible bounds of the scrollView */ 
/* and we add any tiles that should now be present but are missing.    */ 
/***********************************************************************************/ 

- (void)layoutSubviews 
{ 
[self updateResolution]; 
NSLog(@"layoutSubviews "); 
    [super layoutSubviews]; 

    CGRect visibleBounds = [self bounds]; 

    // first recycle all tiles that are no longer visible 
    for (UIView *tile in [tileContainerView subviews]) { 

     // We want to see if the tiles intersect our (i.e. the scrollView's) bounds, so we need to convert their 
     // frames to our own coordinate system 
     CGRect scaledTileFrame = [tileContainerView convertRect:[tile frame] toView:self]; 

     // If the tile doesn't intersect, it's not visible, so we can recycle it 
     if (! CGRectIntersectsRect(scaledTileFrame, visibleBounds)) { 
      [reusableTiles addObject:tile]; 
      [tile removeFromSuperview]; 

     } 
    } 

    // calculate which rows and columns are visible by doing a bunch of math. 
    float scaledTileWidth = [self tileSize].width * [self zoomScale]; 
    float scaledTileHeight = [self tileSize].height * [self zoomScale]; 
    int maxRow = floorf([tileContainerView frame].size.height/scaledTileHeight); // this is the maximum possible row 
    int maxCol = floorf([tileContainerView frame].size.width/scaledTileWidth); // and the maximum possible column 
    int firstNeededRow = MAX(0, floorf(visibleBounds.origin.y/scaledTileHeight)); 
    int firstNeededCol = MAX(0, floorf(visibleBounds.origin.x/scaledTileWidth)); 
    int lastNeededRow = MIN(maxRow, floorf(CGRectGetMaxY(visibleBounds)/scaledTileHeight)); 
    int lastNeededCol = MIN(maxCol, floorf(CGRectGetMaxX(visibleBounds)/scaledTileWidth)); 

    // iterate through needed rows and columns, adding any tiles that are missing 
    for (int row = firstNeededRow; row <= lastNeededRow; row++) { 
     for (int col = firstNeededCol; col <= lastNeededCol; col++) { 

      BOOL tileIsMissing = (firstVisibleRow > row || firstVisibleColumn > col || 
            lastVisibleRow < row || lastVisibleColumn < col); 

      if (tileIsMissing) { 
       UIView *tile = [dataSource tiledScrollView:self tileForRow:row column:col resolution:resolution]; 

       // set the tile's frame so we insert it at the correct position 
       CGRect frame = CGRectMake([self tileSize].width * col, [self tileSize].height * row, [self tileSize].width, [self tileSize].height); 
       [tile setFrame:frame]; 
       [tileContainerView addSubview:tile]; 

       // annotateTile draws green lines and tile numbers on the tiles for illustration purposes. 
       [self annotateTile:tile]; 

      } 
     } 
    } 

    // update our record of which rows/cols are visible 
    firstVisibleRow = firstNeededRow; firstVisibleColumn = firstNeededCol; 
    lastVisibleRow = lastNeededRow; lastVisibleColumn = lastNeededCol;    
} 

答えて

0

パフォーマンスを向上させるためにズームインしてキャッシングしただけで余分なメモリが使用されているためではないと確信していますか? UIImagesのようなものはそうしますが、メモリの警告が当たったときに正しく解放されます。メモリ使用量の増加は必ずしも漏れを意味するものではなく、メモリ使用量を可能な限り最小限に抑えることは常に望ましいことでもありません。なぜなら、使用されていないメモリは占有されているメモリより無駄ですが、実際の使用のためにいつでも割り当てを解除することができます。

0

ピンチジェスチャー(ズームアウト)中にTiledScrollViewクラスのlayoutSubviewsクラスは実装の仕組み(私は70のタイルを測定した)のために多数のタイルを取得します。これにより、あなたが観察したメモリ消費量が大幅に増加します。

ピンチジェスチャーが終了すると、解像度が更新され、reloadDataが呼び出されます。すべてのタイルが削除され、再利用可能なタイルのキューに配置され、新しいタイルのセットが再利用可能なキューから取得されます。新しい解像度に合わせるのに多くのタイルが必要ないので、再使用されるタイルの数はかなり少ないです。

これは、再利用可能なキューが多数の未使用タイル(正確には64個のタイルしか実際に再利用されなかったために)を保持しているため、多くのメモリを無駄にします。

考えられる解決策の1つは、再利用可能なタイルキューを特定の最大数に制限することです。しかし、これは、ピンチング中に非常に多くのタイルを取得するような実装の基本的な欠陥を修正するものではありません。コードが終了すると、コードは常にピンチ時のメモリ消費が急激に増加します。ピンチが終了するとメモリの大部分が解放されますが、再利用可能なタイルキューを制限する場合に限ります。


EDIT

original demo codeは、今日、ステータス "退職文書" を持っています。デモコードは3つのプロジェクト例で構成されていますが、質問は「タイリング」の例です。

関連する問題