2014-01-30 40 views
1

我試圖在UIScrollView中創建一個UIView,其中包含一個簡單的網格(線條作爲行和列)由UIBezierPath或使用CG函數淹沒。問題是,當我有更大的UIScrollView的內容大小(以及更大的子視圖)時,在繪製網格時會分配大量的內存(50MB或更多)。在UIScrollView的子視圖中繪製一個網格分配巨大的內存

UIViewController中包括只是的UIScrollView過整個場景 - 在viewDidLoad中添加子視圖:

@interface TTTTestViewController() 

@property (weak, nonatomic) IBOutlet UIScrollView *scrollView; 

@end 

@implementation TTTTestViewController 

-(void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // create the subview 
    TTTTestView *testView = [[TTTTestView alloc] init]; 
    [self.scrollView addSubview:testView]; 

    //set its properties 
    testView.cellSize = 50; 
    testView.size = 40; 

    // set the content size and frame of testView by the properties 
    self.scrollView.contentSize = CGSizeMake(testView.cellSize * testView.size, testView.cellSize * testView.size); 
    testView.frame = CGRectMake(0, 0, self.scrollView.contentSize.width, self.scrollView.contentSize.height); 

    // let it draw the grid 
    [testView setNeedsDisplay]; 
} 

@end 

,只是繪製使用UIBezierPath/CG功能的網格內部景觀 - 取決於屬性的大小(行/列數)和CELLSIZE (在網格一個單元的寬度/高度):

#define GRID_STROKE_WIDTH 2.0 

@implementation TTTTestView 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     self.backgroundColor = [UIColor clearColor]; 
    } 
    return self; 
} 

- (void)drawRect:(CGRect)rect 
{ 
    [super drawRect:rect]; 
    [self drawGrid]; 
} 

-(void)drawGrid 
{ 
    UIBezierPath *path = [[UIBezierPath alloc] init]; 

    for (int i = 1; i < self.size; i++) { 
      //draw row line 
     [path moveToPoint:CGPointMake(0, self.cellSize * i)]; 
     [path addLineToPoint:CGPointMake(self.bounds.size.width, self.cellSize * i)]; 
      // draw column line 
     [path moveToPoint:CGPointMake(self.cellSize * i, 0)]; 
     [path addLineToPoint:CGPointMake(self.cellSize * i , self.bounds.size.height)]; 
    } 
    [path setLineWidth:GRID_STROKE_WIDTH]; 
    [[UIColor blackColor] setStroke]; 
    [path stroke]; 
    /* 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    CGContextSetLineWidth(context, GRID_STROKE_WIDTH); 
    CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); 

    for (int i = 1; i < self.size; i++) { 
    //draw row line 
    CGContextMoveToPoint(context, 0, self.cellSize * i); 
    CGContextAddLineToPoint(context, self.bounds.size.width, self.cellSize * i); 
    // draw column line 
    CGContextMoveToPoint(context, self.cellSize * i , 0); 
    CGContextAddLineToPoint(context, self.cellSize * i , self.bounds.size.height); 
    } 

    CGContextStrokePath(context); 
    */ 
} 

@end 

例1:self.size是10,self.cellSize是200 => contentSize是2000×2000點以及內視圖的幀=> 18行是淹沒它分配了〜60MB的內存

例2:self.size是30,self.cellSize是70 => contentSize是2100x2100點以及內視圖的幀=> 58行是淹沒和它分配〜67MB存儲器

這些存儲器號碼我可以看到何時調試繪圖方法。無論我如何畫線,在調用[path stroke] resp時都會分配大量內存。 CGContextStrokePath(上下文)。在儀器我可以看到在行最大的內存分配:

12658 0x10200000 VM:CoreAnimation 00:04.092.149•67,29 MB QuartzCore CA ::渲染:: SHMEM :: new_shmem(無符號長)

我在iOS編程方面頗有新意,我到處尋找解決方案,但我仍然不知道: - /任何人都可以請幫我找一些解釋這裏發生了什麼?謝謝:)

回答

5

在蘋果開發者論壇上提出問題後,我發現,這實際上是正確分配內存。這是因爲使用-drawRect:繪製的任何視圖將按照(bounds.size.width * bounds.size.height * contentScale * contentScale * 4)字節的順序使用內存。

創建避免使用網格的最簡單方法是爲每行添加視圖並使用視圖的backgroundColor屬性爲視圖着色。這幾乎不會使用任何內存,因爲視圖(可以是普通的UIViews)不需要調用-drawRect:,因此不會使用額外的內存來存儲繪圖結果。

+2

但是,繪製完成後,由'CA :: Render :: Shmem :: new_shmem(無符號長整數)分配的內存不會減少。永遠是持久嗎? –