您的位置:首页 > 移动开发

IOS app启动动画的实现

2013-12-23 09:55 591 查看
 关于在App启动时播放一段动画,可以用flash直接播放,也可以用多张连续的图片来实现,在项目中,我选择了后者。

通过连续的多张图片做出动画效果,系统自带的UIImageView就能完成这个功能,一开始我也这么做的,但是最后发现内存爆了,占了800M多(iPAD)。(注:一张100K的png图片初始化为Image放到内存后会占用几M到几十M的空间不等)

  最后我选择了通过定时器不断刷新UIImageView.image的方法。

          在这里又被系统忽悠了一把。 [UIImgae imageName: ]和[UIImage imageWithContentsOfFile: ],这两个方法从理论上说,前者是系统分配一块内存缓存图片,并在app生命     周期内一直存在,而后者是暂时存于内存,事后就释放的。我用了后者,发现内存一样爆掉,似乎(肯定)系统并没有释放内存。这个问题困扰了我半天,到底如何才能让系统及时释放这些空间,换个角度想可能更好,手动申请 —— 手动释放。

          于是我换成了[UIImage alloc]initWIthContentsOfFile: ]方法,这样就成功的解决掉了内存无法释放的问题。我的动画图片又106张,测试中发现只占了40-50M的空间,可以接受。

          解决了内存问题,如何能让图片快速刷新就成了当务之急。

          我建了个缓存池,后台异步读取图片到NSMutiableArray中,主线程从array中获取image并定时刷新到ImageView中。这个方法在多核设备中性能有所提高,动画更加流畅。

          下面是核心代码:

 

 

[cpp]

- (void) precache 



    _cacheImages = TRUE; 

    _cacheImageArray = [[NSMutableArray alloc]initWithCapacity:0]; 

 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

        NSLog(@"################################  image swap begin #########################"); 

        UIImage * img = nil; 

        for (int i =1; i < [_imageNames count]; i++) 

        { 

            if(_cacheImageArray.count <= KSwapImageNum) { 

                NSString * name = [_imageNames objectAtIndex:i]; 

                img = [[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:name ofType:nil]]; 

                [_cacheImageArray addObject:img]; 

                [img release];img = nil; 

            }else{ 

                [_requestCondition lock]; 

                [_requestCondition wait]; 

                [_requestCondition unlock]; 

                i--; 

            } 

        } 

        NSLog(@"################################  image swap end #########################"); 

    }); 



 

 

- (void) setImageAtIndex:(NSInteger)index 



    _imageset = TRUE; 

     

    NSString * name = [_imageNames objectAtIndex:index]; 

     

    // load the image from the bundle  

    UIImage * img = nil; 

    if (_cacheImages) 

    { 

        if (_cacheImageArray.count > 0) { 

            img = [_cacheImageArray objectAtIndex:0]; 

            // set it into the view  

            _imageView.image = nil; 

            [_imageView setImage:img]; 

             

            [_cacheImageArray removeObjectAtIndex:0]; 

            if (_cacheImageArray.count <= KSwapImageMinNum) { 

                [_requestCondition signal]; 

            } 

            img = nil; 

        } 

    } 

    else 

    { 

        img = [[UIImage alloc]initWithContentsOfFile: 

               [[NSBundle mainBundle] pathForResource:name ofType:nil]]; 

        // set it into the view  

        [_imageView setImage:img]; 

        [img release];img = nil; 

    } 



- (void) precache

{

 _cacheImages = TRUE;

 _cacheImageArray = [[NSMutableArray alloc]initWithCapacity:0];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLog(@"################################  image swap begin #########################");

        UIImage * img = nil;

        for (int i =1; i < [_imageNames count]; i++)

        {

            if(_cacheImageArray.count <= KSwapImageNum) {

                NSString * name = [_imageNames objectAtIndex:i];

                img = [[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:name ofType:nil]];

                [_cacheImageArray addObject:img];

                [img release];img = nil;

            }else{

                [_requestCondition lock];

                [_requestCondition wait];

                [_requestCondition unlock];

                i--;

            }

        }

        NSLog(@"################################  image swap end #########################");

    });

}

- (void) setImageAtIndex:(NSInteger)index

{

 _imageset = TRUE;

 

 NSString * name = [_imageNames objectAtIndex:index];

   

 // load the image from the bundle

 UIImage * img = nil;

 if (_cacheImages)

 {

        if (_cacheImageArray.count > 0) {

            img = [_cacheImageArray objectAtIndex:0];

            // set it into the view

            _imageView.image = nil;

            [_imageView setImage:img];

           

            [_cacheImageArray removeObjectAtIndex:0];

            if (_cacheImageArray.count <= KSwapImageMinNum) {

                [_requestCondition signal];

            }

            img = nil;

        }

 }

 else

 {

  img = [[UIImage alloc]initWithContentsOfFile:

               [[NSBundle mainBundle] pathForResource:name ofType:nil]];

        // set it into the view

        [_imageView setImage:img];

        [img release];img = nil;

 }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: