IOS app啟動動畫的實現

來源:互聯網
上載者:User

 關於在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;
 }
}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.