UIImageView - 内存问题

时间:2015-03-02 15:44:22

标签: ios objective-c memory-management uiimageview

我正在显示大约50张图像在滚动视图中我遇到了内存问题,每次控制器加载内存使用量增加时,它在仪器应用程序中超过200MB。

我的自定义类的

.h文件     #import

@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文件

#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

这就是我创建自定义类的Object并在Scroll View上显示它们的方法,在我的Controller文件中我使用以下方法

-(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释放内存

感谢。

1 个答案:

答案 0 :(得分:0)

根据视图的布局,有几种方法可能。它看起来怎么样?

但是,您可以使用表格显示图片或使用集合。实际上,为此制作了一个集合。

如果你想坚持滚动视图,那么这50个视图几乎不可见。实际上,您可以在每个视图出现之前设置它们的图像,并在视图离开屏幕时删除图像(将.image设置为nil)。

我制作的App应用程序设计的方式是只有一个且只有一个图像可以全屏显示。当用户滚动其邻居图像时进入视图。 (分页机制) 在我看来,可能的观点数量是不可预测的。虽然这也是一个集合可以实现的,但我去了一个滚动视图。 在那个视图中,我设计了托管滚动视图,它的大小足以容纳三个视图。它们的中间视图在屏幕上可见。 (当显示第一个或最后一个 - 如果有的话 - 视图时应用哪些例外)。 当用户滚动到足够远以使邻居视图完全可见时,我重置滚动视图以使其中间再次可见,将视图移动到刚刚变为可见的中间,将以前可见的视图移动到外端并填充具有新视图的另一个传入结束。 这允许无限滚动而不需要一次在存储器中保存超过4个图像。 (4:刚刚移开的那个,在滚动视图中移动的两个,并且一次在同一个方法中分配新的。)