2011-02-11 60 views
7

我有一個被稱爲一個循環方法,看起來是這樣的範圍內:釋放renderInContext導致一個循環

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
UIImageView *background = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, PAGE_WIDTH, PAGE_HEIGHT)]; 
background.image = backgroundImg; 

for (UIView *view in viewArray) 
{ 
    [background addSubview:view]; 
} 

UIGraphicsBeginImageContext(background.frame.size); 
[background.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

for (UIView *view in background.subviews) 
    [view removeFromSuperview]; 

background.image = nil; 
[background release]; 
[image retain]; 
[pool drain]; 
[image autorelease]; 
return image; 

然而,根據儀器內存監視器,內存使用情況不斷地增高,並直到循環結束纔會出現。 (這會崩潰。)

如果我更換UIGraphicsBeginImageContext與

的UIImage UIGraphicsEndImageContext *圖像= someotherimage;

那麼內存不會尖峯化,但是由於Autorelease池的原因,我在循環的每次迭代中都會分配和減少內存。 (它不會崩潰)

如果我只是註釋掉renderInContext行它工作正常。 (不會崩潰)

因此,看起來好像renderInContext以某種方式保持在圖像上 - 我怎樣才能讓它釋放它?或者有其他的建議請:)

回答

14

當然,經過3天的試驗後,我發現答案(無論如何,無論如何,我很樂意就此發表評論)。

我添加

background.layer.contents = nil; 

UIGraphicsEndImageContext(); 

,並在層緩存的內存是未緩存:)。

+0

你是救世主! – 2013-05-15 10:00:26

0

我沒有使用UIImageView,因此設置layer.contents = nil對我無效。然而,我發現了一個不同的解決方案,儘管不理想,但它的確行得通。看來由renderInContext分配的內存在main_queue空閒之前不會被釋放。所以,我做了以下幾點:

dispatch_queue_t queue = dispatch_queue_create("com.example.imageprocessing", DISPATCH_QUEUE_SERIAL); 

for (int k = 0; k < images.count; ++k) { 
    dispatch_async(queue, ^{ 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      @autoreleasepool { 
       ... 
       UIGraphicsBeginImageContext(self.view.bounds.size); 
       [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
       image = UIGraphicsGetImageFromCurrentImageContext(); 
       UIGraphicsEndImageContext(); 
       ... 
      } 
     } 
    } 
} 

這解決了我的記憶問題。我沒有處理很多圖像,所以我不知道性能如何受到影響。