如何从动画UIImage数组中释放内存

时间:2011-12-03 17:07:18

标签: iphone xcode memory-management uiimageview uiimage

我想知道如何从动画阵列中释放内存,不知何故,在动画中,动画图片占用了24MB的真实内存。我该怎么办才能释放记忆?在Mac OS中,总图片文件大小约为3MB。

* 编辑: *很酷,我在构建设置中启用了ARC设置,不再崩溃......但内存使用率仍然在80 - 120mb物理内存中徘徊.....

这是为图像运行的行。

    -(void)defaultSetup
{

    self.imageArray = [[NSMutableArray alloc] initWithObjects:
                       [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"default/d7.jpg"]],
                        [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"default/d9.jpg"]],
                        [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"default/d11.jpg"]],
                        [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"default/d27.jpg"]],
                        [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"default/d6.jpg"]],                        
                        nil];
    self.defaultID = [[NSMutableArray alloc] initWithObjects:@"0",@"1",@"2",@"3",@"0",nil];
    self.defaultImageCaption = [[NSMutableArray alloc] initWithObjects:@"Ver",@"Green",@"Red",@"Cru",@"East",nil];      


    NSUInteger count = [self.defaultID count];
    NSLog(@"Count %i",[self.defaultID count]);
    NSMutableArray *randomImgName = self.imageArray;
    NSMutableArray *randomID = self.defaultID;
    NSMutableArray *randomName = self.defaultImageCaption;

    for (NSUInteger i = 0; i < count; ++i) {
        // Select a random element between i and end of array to swap with.
        int nElements = count - i;
        int n = (arc4random() % nElements) + i;
        [randomName exchangeObjectAtIndex:i withObjectAtIndex:n];
        [randomImgName exchangeObjectAtIndex:i withObjectAtIndex:n];
        [randomID exchangeObjectAtIndex:i withObjectAtIndex:n];
    }
    self.imageArray = randomImgName;
    self.defaultID=randomID;
    self.defaultImageCaption=randomName;

    NSLog(@"default filename %@",self.defaultImageCaption);
    NSLog(@"default ID %@",self.defaultID);
    self.imageViewTop.alpha = 1.0;
    self.imageViewBottom.alpha = 0.0;
    self.imageViewBottom = [[[UIImageView alloc] initWithFrame:CGRectMake(0,44,320,367)] autorelease];
    self.imageViewTop = [[[UIImageView alloc] initWithFrame:CGRectMake(0,44,320,367)] autorelease];
    [self.view addSubview:imageViewTop];
    [self.view addSubview:imageViewBottom];

    self.buttonCaption = [UIButton buttonWithType:UIButtonTypeCustom];
    //default placement
    self.buttonCaption.frame = CGRectMake(245, 365, 70, 30);
    //[buttonCaption setTitle:@"\u00A9"  forState:UIControlStateNormal];
    [self.buttonCaption addTarget:self action:@selector(buttonCheck) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.buttonCaption];

    [self nextAnimation:buttonCaption.frame.size.width]; 

}

-(void)nextAnimation:(float)previousWidth {

    //picture loop
    imageViewTop.image = imageViewBottom.image;
    imageViewBottom.image = [imageArray objectAtIndex:[imageArray count] - 1];

    [imageArray insertObject:imageViewBottom.image atIndex:0];
    [imageArray removeLastObject];
    imageViewTop.alpha = 1.0;
    imageViewBottom.alpha = 0.0;

    //Name Caption
    NSString * tempCaption = [defaultImageCaption objectAtIndex:[defaultImageCaption count]-1];
    self.dID = [defaultID objectAtIndex:[defaultID count]-1];

    // make the buttons content appear in the top-left
    [buttonCaption setContentHorizontalAlignment:UIControlContentHorizontalAlignmentCenter];
    [buttonCaption setContentVerticalAlignment: UIControlContentVerticalAlignmentCenter ];



    [defaultImageCaption insertObject:tempCaption atIndex:0];
    [defaultImageCaption removeLastObject];
    [defaultID insertObject:dID atIndex:0];
    [defaultID removeLastObject];

    [UIView animateWithDuration:1 delay:2 options:0       
                     animations:^{                          
                         [buttonCaption setTitle:tempCaption  forState:UIControlStateNormal];
                         //NSLog(@"Name %@",tempCaption );
                         //NSLog(@"ID %@",dID);
                     } 
                     completion:^(BOOL  completed)
     {
     }];  

3 个答案:

答案 0 :(得分:1)

使用allocinitinitWith*创建内容时(如imageArray所述),您可以使用release发布内容:< / p>

[self.imageArray release];

如果涉及autoreleaseretain来电,事情会变得有点棘手。但他们似乎没有在这里发挥作用。

答案 1 :(得分:1)

阅读Cocoa内存管理。 (我假设你没有使用ARC(自动引用计数)。)顺便说一句,我考虑使用ARC,它会让你的生活更轻松。 (这是一种编译时技术,因此向后兼容较旧的iOS运行时,但是你不会在较旧的iOS运行时获得弱的参考支持。)

总结内存管理规则:增加对象保留计数的所有内容应该通过某些方面来减少保留计数。

增加保留计数的事项:

self.propertyName = anInstance,当使用retain属性声明该属性时。

[objectInstance retain]

[Class alloc][Class new][objectInstance copy]或以copy开头的变体。

将对象添加到标准集合类(例如NSArray)。

减少保留计数的事项:

self.propertyName = <some other object instance or nil>,当使用retain属性声明该属性时。

[objectInstance release]

[objectInstance autorelease](稍后会导致释放)。

从标准集合类中删除对象(例如NSArray)。

答案 2 :(得分:0)

如果你懒洋洋地加载图片(而不是获取UIImages数组imageArray制作他们位置的数组),你可以节省大量内存,并且可以轻松清理UIImage实例。 通过这样做,加载到内存中的最大图像不会超过3;它可以节省RAM。

按要求提供的示例:

初始化数组时

self.imageArray = [[NSMutableArray alloc] initWithObjects:
               @"default/d7.jpg",
               @"default/d9.jpg",
               @"default/d11.jpg",
               @"default/d27.jpg",
               @"default/d6.jpg",                        
               nil];
加载实际图片时

NSString* imgPath = [imageArray objectAtIndex:[imageArray count] - 1];
imgPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:imgPath];
imageViewBottom.image = [UIImage imageWithContentsOfFile:imgPath];

让我知道它是否有帮助!