iOS——app启动动画
2015-08-17 15:11
453 查看
关于在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] view
plaincopy
- (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;
}
}
通过连续的多张图片做出动画效果,系统自带的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] view
plaincopy
- (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;
}
}
相关文章推荐
- Android中logcat和adb使用
- ios弹出软键盘时fixed失效及点击空白处隐藏层的解决办法
- Android根据反射获取R文件中的字段值即id值
- Android中的Handler机制
- android中imageButton显示本地图片
- Android错误之--Platform MNC is a preview and requires application manifest to set minSdkVersion to 'M
- CocoStudio:ImageView分析
- UIWebView与js交互(一)
- androidのstring.xml转译、特殊字符问题处理
- 30多个iOS常用动画,带详细注释
- Unity打包android的apk与数据包.obb分离和apk签名
- Android中几种图像特效处理的集锦!!
- [iOS]调用系统相机,相册,闪光灯
- iOS编程——Swift语法之 "?" 和 "!"
- [转]cocos2dx中用外部浏览器打开url
- Cocos2d-x能够实现的效果总结
- Unity3d的单例及场景间的数据传递
- Objective-C 数据类型定义的标示符(一)
- android 实现真正意义上的服务及源代码下载
- Swift版 ScrollView和UITouch事件冲突