2015-03-02 156 views
0

我顯示了大約50個圖像在滾動視圖中,我遇到了內存問題,每當Controller加載內存使用率增加並且它在儀表應用程序中超過200MB。我的自定義類的UIImageView - 內存問題

.h文件中 #進口的我的自定義類

#import "AnimalGrid.h" 

@implementation AnimalGrid 
{ 
    UIImageView *_contentView; 
    UILabel  *_accessoryView; 
    UIImage  *displayImage; 
    NSString  *displayText; 
} 

@synthesize Delegate = _Delegate; 

-(id)initGridWithFrame:(CGRect)frame andAnimalImage:(UIImage*)image andAnimalName:(NSString*)animalname andTag:(int)tag 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 

     self.backgroundColor = [UIColor clearColor]; 
     self.animalName = animalname; 
     self.animalTag = tag; 
     displayImage = image; 
     displayText = animalname; 
     CGFloat contentHeight = frame.size.height * 0.8; 

     if (animalname == nil || animalname.length == 0) 
      contentHeight = frame.size.height; 

     CGFloat margin = 0; 
     if (displayImage.size.height < contentHeight) 
     { 
      margin = contentHeight - displayImage.size.height; 
     } 


     UIView *placeholderView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, contentHeight)]; 
     placeholderView.backgroundColor = [UIColor clearColor]; 
     if (image.size.height > placeholderView.frame.size.height) 
     { 
      _contentView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, placeholderView.frame.size.height)]; 
     }else if (image.size.height < placeholderView.frame.size.height){ 

      CGFloat margin = placeholderView.frame.size.height - image.size.height; 
      _contentView = [[UIImageView alloc]initWithFrame:CGRectMake(0, margin, frame.size.width, placeholderView.frame.size.height - margin)]; 

     } 

     _contentView.backgroundColor = [UIColor clearColor]; 
     _accessoryView = [[UILabel alloc]initWithFrame:CGRectMake(0, frame.size.height * 0.7, frame.size.width, frame.size.height-frame.size.height * 0.7)]; 
     _accessoryView.numberOfLines = 2; 
     _accessoryView.backgroundColor = [UIColor clearColor]; 
     _accessoryView.font = [UIFont fontWithName:@"HFFAirApparent" size:23]; 
     _accessoryView.textColor = [UIColor orangeColor]; 

     [placeholderView addSubview:_contentView]; 
     [self addSubview:placeholderView]; 

     if (animalname != nil || animalname.length > 0) 
     [self addSubview:_accessoryView]; 

     if(image) 
      _contentView.image = image; 

     _contentView.contentMode = UIViewContentModeScaleAspectFit; 
     _accessoryView.text = animalname; 
     _accessoryView.numberOfLines = 0; 
     [_accessoryView sizeToFit]; 

     CGFloat w = self.bounds.size.width/2; 
     _accessoryView.frame = CGRectMake(w - (_accessoryView.frame.size.width/2), _accessoryView.frame.origin.y, _accessoryView.frame.size.width, _accessoryView.frame.size.height); 

     UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapedOnImage:)]; 
     singleTap.numberOfTapsRequired = 1; 
     singleTap.numberOfTouchesRequired = 1; 

     [_contentView addGestureRecognizer:singleTap]; 
     _contentView.userInteractionEnabled = YES; 
     self.userInteractionEnabled = YES; 
    } 

    return self; 
} 

-(void)setFont:(UIFont*)font 
{ 
    _accessoryView.font = font; 
} 


-(void)tapedOnImage:(id)sender 
{ 
    if ([_Delegate respondsToSelector:@selector(animalGrid:tappedAtIndex:andName:)]) { 
     [_Delegate animalGrid:self tappedAtIndex:self.animalTag andName:self.animalName]; 
    } 
} 

@end 

@class AnimalGrid; 

@protocol AnimalGridViewDelegate <NSObject> 
-(void)animalGrid:(AnimalGrid*)animalgridview tappedAtIndex:(int)index andName:(NSString*)animalName; 
@end 

@interface AnimalGrid : UIView 

@property(nonatomic, strong) UIImage   *animalImage; 
@property(nonatomic, copy)  NSString  *animalName; 
@property(nonatomic) int  animalTag; 

@property (nonatomic, assign) id <AnimalGridViewDelegate> Delegate; 

-(id)initGridWithFrame:(CGRect)frame andAnimalImage:(UIImage*)image andAnimalName:(NSString*)animalname andTag:(int)tag; 
-(void)setFont:(UIFont*)font; 
@end 

.m文件而這就是我正在創建我的自定義類的對象,並顯示他們通過滾動查看,在我的控制器文件中,我使用以下方法

-(void)setGridAnimals 
{ 
    @try { 
     [self creatingGridsWithCompletion:^(BOOL done, NSMutableArray *arr) 
     { 
      for (int i = 0; i < arr.count; i++) 
      { 
       UIView *gView = [arr objectAtIndex:i]; 
       [gridScrollView addSubview:gView]; 
      } 
      gridScrollView.scrollEnabled = YES; 
      gridScrollView.pagingEnabled = YES; 
      gridScrollView.bounces = YES; 
      gridScrollView.contentSize = CGSizeMake(gridScrollView.frame.size.width, gridScrollView.frame.size.height*arr.count); 
      [aView hideIndicatorView:YES]; 
     }]; 
    } 
    @catch (NSException *exception) { 
     NSLog(@" Exception is = %@ ",exception.description); 
    } 
    @finally { 

    } 


} 


-(void)creatingGridsWithCompletion:(completionBlock)complete 
{ 
    @autoreleasepool { 
     NSMutableArray *pageArray = [NSMutableArray new]; 
     int rowcount = 3; 
     int columncount = 5; 

     CGFloat width = gridScrollView.frame.size.width/columncount - 5; 
     CGFloat height = gridScrollView.frame.size.height/rowcount - 5; 

     int pagecount = gridAnimalArray.count/(rowcount*columncount); 

     if (gridAnimalArray.count%(rowcount*columncount)) 
     { 
      pagecount += 1; 
     } 
     //pagecount = 1; 
     int x = 0; 
     for (int i = 0; i < pagecount; i++) 
     { 
      UIView *page = [[UIView alloc]initWithFrame:CGRectMake(0, x, gridScrollView.frame.size.width, gridScrollView.frame.size.height)]; 
      for (int j = 0; j < rowcount; j++) 
      { 
       for (int k = 0; k < columncount; k++) 
       { 
        int tag = (i*(rowcount*columncount))+(j*columncount)+k+1; 
        if (tag > gridAnimalArray.count) 
        { 
         break; 
        } 
        YEAnimal *animal = [gridAnimalArray objectAtIndex:tag-1]; 
        NSString *name = [[animal.GridName componentsSeparatedByString:@"."] objectAtIndex:0]; 
        UIImage *gridImg; 
        if ([[NSFileManager defaultManager]fileExistsAtPath:[[NSBundle mainBundle] pathForResource:name ofType:@"png"]]) 
        { 
         NSString * imgpath= [ [ NSBundle mainBundle] pathForResource:name ofType:@"png"]; 
         gridImg=[UIImage imageWithContentsOfFile: imgpath]; 
        }else if ([[NSFileManager defaultManager]fileExistsAtPath:[[NSBundle mainBundle] pathForResource:name ofType:@"jpg"]]) 
        { 
         NSString * imgpath= [ [ NSBundle mainBundle] pathForResource:name ofType:@"jpg"]; 
         gridImg=[UIImage imageWithContentsOfFile: imgpath]; 
        } 

        AnimalGrid *grid = [[AnimalGrid alloc]initGridWithFrame:CGRectMake((k * width)+5, (j*height), width, height) andAnimalImage:gridImg andAnimalName:animal.SpeciesName andTag:tag]; 
        grid.backgroundColor = [self getColor]; 
        [grid setDelegate:self]; 
        [page addSubview:grid]; 
       } 
      } 

      [pageArray addObject:page]; 
      x += gridScrollView.frame.size.height; 
     } 

     complete(YES,pageArray); 
    } 
} 

這是網格的外觀:http://s17.postimg.org/x9xdfl4j3/i_OS_Simulator_Screen_Shot_Mar_3_2015_1_54_45_P.png

所以,我知道我應該使用[UIImage imageWithContentsOfFile:]來代替[UIImage imageNamed:]來加載圖像,但它仍然不能幫助我。

有沒有辦法,我可以釋放ImageViews

由於釋放內存的任何方式。

+0

歡迎來到Stack Overflow。預計加載50張圖片需要佔用大量RAM。是否有您正在嘗試解決的具體問題?你有什麼嘗試? – 2015-03-02 15:47:43

回答

0

根據視圖的佈局,有幾種可能。它看起來怎樣?

但是,您可以使用表格來顯示照片或使用集合。其實收集是爲了這個。

如果您想堅持滾動視圖,那麼這50個視圖幾乎不可見。您可以在每個視圖出現之前實際設置其圖像,並在視圖移出屏幕時移除圖像(將.image設置爲nil)。

我最近製作的一個應用程序,其設計方式是隻有一個圖像可以全屏顯示。當用戶滾動其鄰居圖像進入視野。 (分頁機制) 在我看來,可能的視圖數量是不可預測的。雖然這也可以通過一個集合來實現,但我去了一個滾動視圖。 在這個視圖中,我設計了一個託管滾動視圖,它足以容納三個視圖。它們的中間視圖在屏幕上可見。 (當顯示第一個或最後一個 - 如果有的話 - 顯示時應用哪些例外)。 當用戶滾動足夠遠以使鄰居視圖完全可見時,我重置滾動視圖,使其中間再次可見,將視圖移動到剛剛變爲可見的中間,將以前可見的視圖移動到外端,用新視圖填充另一個傳入端。 這允許無限滾動,不需要一次保存超過4張圖像。 (4:剛移動的那個,在滾動視圖內移動的兩個和​​新的一次在同一個方法內分配)。

+0

嗨,我已經添加了一個鏈接,告訴你如何看起來我的網格,我遵循你的指示,現在只加載可見的圖像滾動視圖,當用戶向上或向下滾動我刪除以前的對象和創建下一組對象以顯示。這肯定會降低內存壓力,但是每次控制器加載時內存使用量仍會增加,但增量非常低。 – 2015-03-03 08:36:01

+0

現在,您已將鏈接添加到佈局,我建議您改爲使用集合視圖。它有很多您需要的服務,例如它爲您提供了重新使用單元格的選項(因此也提供了圖像),並且它只關心爲當前可見的單元格創建單元格(因此也就是圖像)。 – 2015-03-04 09:32:35