ios移动开发内存优化总结

阿弥陀佛,善哉善哉! 这几天在公司闲来无事说点本人ios开发中总结的一些经验,本人老菜鸟一只,若有错误,还请路过大侠指点!ios开发最麻烦的一点应该就是内存吧,当然如果你不用starling开发的话,性能也是一个比较大的麻烦,因为渲染所带来的性能消耗是相当大的。由于本人是用starling开发,所以性能这块也没有什么可以多说的,就先说说内存吧。

如果你的应用在手机上总是一卡一卡的,那么恭喜你 ~~~ 内存紧张了。 我以前做过一个flash原生的游戏,游戏开始跑的挺顺畅的,但是玩久了就会一卡一卡的,而且越往后间隔时间越短,到最后卡得动不了了,直到闪退,当时就有人说是不是又很多enterFrame呀,导致计算量变大呀。我当时只是笑笑的看着他不说话,心里无限bs,没见识。后来查出是有一个矢量图的sprite,在不停的创建,但是没有得到释放,所以每次加一点点内存,开始不明显还挺流畅,到后面就hold不住了,整个就是不停的执行内存回收。 效率低的表现方式一般是帧频降低,游戏很慢,但是帧数稳定,不会卡顿。而卡顿一般就是以下几个原因:1,内存紧张,程序不停的执行内存回收,内存紧张了垃圾回收的执行周期就会缩短,垃圾回收可以在内存不紧张的时候执行不会卡,只会掉帧,但是如果内存很紧张的时候就会卡顿;2.后台下载东西,联网,比如广告,登录gameCenter(小小的吐槽下,本人所在公司最喜欢加广告了,蛋疼)等;3.电量低了(这个可能大家都知道,呵呵)。

苹果手机内存一般都不大吧,不比安卓,所以内存还是要相当的节省。内存最主要的消耗就是在纹理上了,所以纹理一定要尽量省着点用,每一张纹理图集都要尽量摆满,不要有太多的空白区域,有一些纹理能重用的就尽量重用,比如按钮,可以你的按钮背景都是一样的,不同的就是按钮上面的图标或者文字(如play,menu等),这时你最好的做法是把这个按钮拆开,按钮的背景独立出来,所有按钮都用这个一个,然后再在上面加文字。文字如果比较多的话推荐使用位图字体,因为即使是使用starling,starling自带的TextField的渲染效率也不是很令人满意。位图字体这里不多少。

如果游戏中的人物动作比较多,强力推荐用骨骼动画dragonBones。这个东西很容易上手,我基本上没有怎么查过资料,就是看了一下自带的几个demo,就开始摸索着用了。我游戏中有11个角色,每个角色的大小差不多是180*90像素,每个角色都有6~7套动作,最后做完放一起到处才一张1024*1024大小的图片,如果用starling的帧动画的话,保守估计可能会要4张2048*2048了,那我的游戏光导入放这些人物素材就得闪退了。而且dragonBones的每个关节可以调整角度,如果你的角色武器是枪或者是弓箭的话你就赚大了,你可以旋转枪的武器,做到360度攻击了,如果是帧动画,你可能就没法实现这个效果了,只能尴尬的攻击正前方了,那多没意思。

在对象的使用上也应该尽量节省,多使用对象池缓存,缩短内存回收时间。在手机上创建对象也要注意,不知道是不是有很多人都喜欢游戏一开始就一次性给常用的对象创建个几十个,如果一次性创建的对象太多,可能会出现停顿时间,影响游戏体验,建议如果是小怪或者树木这种,不会同时大量出现的一次就创建一两个,如果取的时候对象池里面没有了,再创建几个,不要太多,多了就是浪费,你永远要记住对象池里的东西如果你不手动删除引用是不会在垃圾回收的时候释放的,会一直占用内存。对于那些金币之类每次一用就是几十个的,你就可以一批次的创建几十个。使用对象池一定要记得用完要放回池子重新初始化。在starling中每次对象从显示列表移除的时候我都喜欢是用removeFromParent(...)方法,在使用这个方法的时候如果你不需要这个对象调用dispose()方法,就不要在removeFromParent()

的参数里面填true了。因为我有时候填了true之后,下次拿来用的时候对象就不见了,不是null,是看不到了,因为它的纹理可能被你释放掉了。 注意,如果内存依旧紧张,你可以把对象池中一些暂时可能用不到的对象释放掉。如果高级一点不怕麻烦的话,你可以定期多次对比一下对象池中闲置的对象数量,把长时间未使用的对象释放掉。总之对象池是双刃剑,有利有弊,自己权衡。

现在能想起来的差不多就这些,都是文字,没有代码,不知道会不会看的不爽,不过都是些理论的东西也没什么代码可以贴的,希望对菜鸟们有用,若有错误请指出,轻喷!原创手打不容易呀

 

第二篇:iOS开发初学者详细总结

曾尝试webview嵌在tableview里,为了让webview跟tableview一起滚动,把webview的大小设为webview里的内容大小,让webview不出滚动条,从而能跟着tableview的滚动条一起滚。这样做的后果是每次webview都一次性渲染整个页面

基础篇

为什么对一个变量release后还要设为nil

对一个变量release后,这个变量指向的内存释放了,但这个变量本身没变,仍指向原来的内存地址。若这个变量在释放后被访问,或者被重复release,就会导致应用崩溃。设为nil后这个变量指向0×00,可以保证程序以后访问不到原先的内存地址,对nil进行release也没任何问题。

使用类成员时,前面加不加self.有什么区别

不加self.调用的是成员本身,加self.后实际上调用了其成员的get set方法。

例:

//.h

@property (nonatomic, retain) NSString *name

//.m

name = @"bang" //没有retain,随时会被释放

NSString *str = self.name //等于NSString *str = [self name];

self.name = @"bang" //等于[self setName:@"bang"]; 这时在set方法里retain了这个字符串

技巧篇

内存泄漏

可以通过xcode的编译工具Product-Analyze检查函数块范围内可能的泄漏点(外带会提示一些可能有的错误)。

用leaks工具监测出来的泄漏查找方法是跟踪其代码提示中出现的变量,经常这个变量是在提示的调用堆栈以外的地方泄漏的。若实在查不到,最终办法是重写这个变量的retain和release方法,debug,从调用堆栈看是谁retain了它而没有release。

要注意的是,用CFXXCreate(例如CFArrayCreate)生成的变量要用CFRelease释放。 数据存储

如无搜索需要,可以将一个数据对象直接序列化后存到sqlite,取出时直接反序列化为对象使用。序列化需要数据类实现NSCoding协议,实现encodeWithCoder和initWithCoder两个方法就行,若有多个数据对象,可以写个基类实现这两个方法,并在这里面利用反射枚举自身所有变量去encode和decode,一劳永逸,具体实现网上找找就有了。

组件篇

UINavigationController头尾显示隐藏

在用NavigationController去管理view的push和pop时,需要根据不同的view设置是否显示NavigationBar和ToolBar,一开始在错误的地方设置了,导致有时该显示NavigationBar和ToolBar时不显示的情况,后来发现在viewWillAppear上设置万无一失。别笑我土鳖,没好好去理解它整个流程,一直没发现。

- (void) viewWillAppear:(BOOL)animated{

[super viewWillAppear:animated];

[self.navigationController setToolbarHidden:NO];

[self.navigationController setNavigationBarHidden:NO];

}

UITableView游标式渲染

tableView的机制大概是:先定好总行数,某一行滚入视图范围时,回调一个函数去取view出来显示。这一行滚出视图再滚入时仍会继续回调这一函数取view。有这样的机制就是说无论你table里的数据有多少,都可以全部放入table中不用分页,因为不用一次性把所有数据都取出来,只在需要显示的时候根据游标去取对应的数据就行了。

可能这是APP组件很自然的方式不用说明,但在web上页面上的数据和元素都是要一次性载入内存的,做久了web,一开始没想到它这样的实现机制,导致我们走了不少弯路。 UIWebView渲染范围

UIWebView不是根据可视范围决定每次的渲染范围,而是根据自身控件的frame大小决定。

曾尝试webview嵌在tableview里,为了让webview跟tableview一起滚动,把webview的大小设为webview里的内容大小,让webview不出滚动条,从而能跟着tableview的滚动条一起滚。这样做的后果是每次webview都一次性渲染整个页面,内存占用多性能很差,而且在放大缩小这个webview时,渲染放大的整个页面更吃力,出现不能忍受的性能。解决办法是让webview定住高度为一整屏iphone的高度,限制了webview每次的渲染范围为可视范围,性能大好。带来的问题是无法随tableview滚动,但可以以其他方式优化体验。最近看到新版的ZAKER也是这样做的。

个人感觉篇

界面布局调整非常麻烦,让人怀念web了。界面描述方法XIB感觉晦涩难学,至今不会,没有CSS+HTML来得方便。

有编译器把关,少了像写js时多写or写错一个字符查半天的问题。

Object-C写起来各种变量函数和变量调用很长,没有js的短小精悍来得爽。

第一次编写涉及手动内存管理的程序,挺有意思,没想象中难,但有些内存管理导致的bug很难查。

虽然APP不像web那样随时更新,但也不像传统PC客户端升级那么麻烦,用户更新意愿更强,还是适合快速迭代的。

细节是可以决定成败,但得看你把什么定成细节。

最后,0 bug的程序不存在,极致是把最主要的事做好。done is better than perfect。

相关推荐