简体   繁体   English

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

[英]how to release memory from animating UIImage Array

I will like to know how to release the memory from the animating array, somehow in instruments the animating picture are eating up 24MB of real memory. 我想知道如何从动画阵列中释放内存,不知何故,在动画中,动画图片占用了24MB的真实内存。 what should i do to release the memory ? 我该怎么办才能释放记忆? the total picture file size are about 3MB in Mac OS. 在Mac OS中,总图片文件大小约为3MB。

* EDIT: *Cool, i enabled the ARC setting in the build setting, no longer crashing...but memory usages still hovering around 80 - 120mb physical memory..... * 编辑: *很酷,我在构建设置中启用了ARC设置,不再崩溃......但内存使用仍然在80 - 120mb物理内存中徘徊.....

this is the line that run for the image. 这是为图像运行的行。

    -(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)
     {
     }];  

When something is created with alloc and init or an initWith* (as is done here with imageArray ) you can release it with release : 当与物质创造的allocinitinitWith* (如与在这里完成imageArray ),你可以用它释放release

[self.imageArray release];

If there's autorelease or retain calls involved, things can get a little bit more tricky. 如果有autoreleaseretain涉及的电话,事情会变得有点棘手。 But they don't seem to come into play here. 但他们似乎并没有在这里发挥作用。

Read up on Cocoa memory management. 阅读Cocoa内存管理。 (I'm assuming you're not using ARC (automatic reference counting).) Btw, I'd consider using ARC, it makes your life easier. (我假设你没有使用ARC(自动引用计数)。)顺便说一句,我考虑使用ARC,它会让你的生活更轻松。 (It's a compile-time technology, so is backwards compatible with older iOS runtimes, but you don't get weak reference support on older iOS runtimes.) (这是一种编译时技术,因此向后兼容较旧的iOS运行时,但是你不会在较旧的iOS运行时获得弱的参考支持。)

To summarise the memory management rules: everything that increases your retain count on an object should be balanced by something that decreases the retain count at some point. 总结一下内存管理规则:增加对象保留计数的所有内容应该通过减少某些时候保留计数的东西来平衡。

Things that increment the retain count: 增加保留计数的事情:

self.propertyName = anInstance , when that property is declared with retain property. self.propertyName = anInstance ,当使用retain属性声明该属性时。

[objectInstance retain] . [objectInstance retain]

[Class alloc] , [Class new] , [objectInstance copy] or variants beginning with copy . [Class alloc][Class new][objectInstance copy]或以copy开头的变体。

Adding an object to a standard collection class (eg NSArray ). 将对象添加到标准集合类(例如NSArray )。

Things that decrement the retain count: 减少保留计数的事情:

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

[objectInstance release]

[objectInstance autorelease] (causes a release at some later time). [objectInstance autorelease] (稍后会导致释放)。

Removing an object from a standard collection class (eg NSArray ). 从标准集合类中删除对象(例如NSArray )。

If you load the images lazily (rather than getting array of UIImages imageArray make array of their locations) you can save lot of memory, and can easily clean up UIImage instances. 如果你懒洋洋地加载图像(而不是获取UIImages的数组imageArray make其位置数组),你可以节省大量内存,并可以轻松清理UIImage实例。 By doing this, the max images loaded in memory would not be more than 3; 通过这样做,加载到内存中的最大图像不会超过3; it can save RAM. 它可以节省RAM。

example as requested: 示例请求:

while initializing the array, 在初始化数组时,

self.imageArray = [[NSMutableArray alloc] initWithObjects:
               @"default/d7.jpg",
               @"default/d9.jpg",
               @"default/d11.jpg",
               @"default/d27.jpg",
               @"default/d6.jpg",                        
               nil];

while loading actual image 在加载实际图像时

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

Let me know if it helps! 如果有帮助,请告诉我!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM