iOS内存优化

1、运行MemoryProblems后,运行崩溃出现EXC_BAD_ACCESS,启动NSZombieEnabled,选中Edit Scheme并点击,Run -> Diagnostics -> Enable Zombie Objects(悬挂指针的检测),设置完之后,再次运行和点击页面,虽然会再次crash,但这次控制台打印了有用信息,点击Continue program execution按钮继续运行,对比找到相同地址并修改(启动MallocStackLogging)

常见原因:某变量被assign修饰,对变量值后,它的对象就马上释放,而变量也不是strong而是weak,此时仍然使用就会导致程序crash

2、手动静态分析:应用Product—>Analyze或快捷键shift + command + b进行内存泄漏的初步检测

    自动静态分析:在Build Settings启用Analyze During 'Build',每次编译时都会自动静态分析

3、可以在xcode的build setting中打开implicit retain of ‘self’ within blocks,xcode编译器会给出警告,逐个排查警告

4、应用Leak Instrument进行内存泄露查找:点击Xcode的菜单栏的 Product -> Profile 启动Instruments,出现Instruments的工具集,选中Leaks子工具点击,点击红色圆点按钮启动Leaks工具,在Leaks工具启动同时,模拟器或真机也跟着启动,启动Leaks工具后,它会在程序运行时记录内存分配信息和检查是否发生内存泄露

首先点击Leak Checks时间条那个红色叉,点击红色叉后,下面显示Leaks By Backtrace,双击某行内存泄露调用栈,会直接跳到内存泄露代码位置

Leak Instrument有Cycles & Roots界面:Persistent Bytes和#Persistent。#Persistent是object的数量,也就是allocation的次数,而Persistent Bytes是具体的内存大小。#Persistent是我们需要关注的,内存有没有泄露也是看这个值是不是只增不减。

Allocations:启动Allocations,勾选列表最上边的,右边设置勾选:Discard unrecorded data upon stop、Identify virtual C++ objects、* isContain…Record 

列表勾选VM

Generation Analysis

这个功能是非常有用的,一般是这样用的:进入一个页面前mark一下,在退出这个页面的时候再mark一下可以比较哪些内容增加了,就可以具体分析哪些内存没有被释放

Call Tree:需要我们把列表展示类型切换成Call Trees,能够非常清晰的看到调用树

Separate by Category:按照类别隔开,我们钩上看看效果

Separate by Thread:按照线程划分,我个人不是很喜欢这种划分,因为我不是很关心线程

Invert Call Tree:反转调用,我们给一张对比图就不需要解释了

Hide System Libraries:这个似乎是必钩的,因为我们目前只关心自己的方法,不关心系统的

Flatten Recursion:扁平化递归

Data Mining:数据挖掘,这是一个很具有噱头的功能

点击Symbol、Library会自动把你选中的行的符号、库加到小框中

符号和库有两个选项,就是是否过滤改行;点击Restore会去掉小框中的选中行

5、通过查看dealloc是否调用查看某个class是否泄漏问题

- (void)dealloc

{

 NSLog(@"release XXXXViewController");

}

方法: __weak XXXXViewController *weakSelf = self;在Block里用weakSelf

常见问题:

1、UITextField在iOS 11内存泄漏问题:UITextField没释放原因使用secureTextEntry属性,解决方案

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {

 if (textField == self.passWordTextField) {

textField.secureTextEntry = YES;

}else {

textField.secureTextEntry = NO;

    }

 return YES;

}

2、使用CGMutablePathRef path = CGPathCreateMutable();时出现Potential leak of an object stored into 'path’,解决方案

CGPathRelease(path);

以creat,copy作为关键字的函数都是需要释放内存的,注意配对使用。比如:CGColorCreate<-->CGColorRelease

3、The 'viewWillDisappear:' instance method in UIViewController subclass 

XXX is missing a [super viewWillDisappear:] callm,解决方案

- (void)viewWillAppear:(BOOL)animated {

[super viewWillAppear:animated];

}

4、调用

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

方法之后在不需要NSTimer时及时调用[self.timer invalidate];千万不要在dealloc方法中调用,因为NSTimer强引用self,所以不会执行dealloc方法。

5、对象之间的循环引用:例子:两个ViewController都需要使用对方,这个时候可以用@class ; 

说明:在 .h 中引入某个类, @class 指的是 当前文件 只是引入类名, 并没有使用类里面的东西. 想要在 .m 里面使用 类的内容的话, 还是要 #import <>, 这种情况跟 上面的对象之间的防止循环引 有点不一样

6、如果是C申请的内存,注意new delete, malloc free的配对处理。

7、图片相关:

缓存:imageNamed:

只需传入文件名.扩展名即可。

可以加载bundle中任意位置的图片,包括main bundle中其他bundle的。

imageNamed方法创建对象的步骤如下:

7.1根据图片文件名在缓存池中查找图片数据,如存在,则创建对象并返回;

7.2如果不存在,则从bundle中加载图片数据,创建对象并返回;

7.3如果相应的图片数据不存在,返回nil。

不缓存:imageWithContentsOfFile:

必须传入图片文件的全名(全路径+文件名)。

无法加载Images.xcassets中的图片。

对于大的图片且偶尔需要显示的应放到工程目录下,不要放到Assets.xcassets中;并使用imageWithContentsOfFile加载不让系统缓存

background.image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/*.png"]];

对于经常需要展示的小图片放到Assets.xcassets中让系统缓存,使用imageNamed加载

background.image = [UIImage imageNamed:@"*.png"];

不常用大图:将imageView.image = [UIImage imageNamed:nameArr[index]];

改为imageView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:nameArr[index] ofType:@"png"]];

8、出现VM:CG raster data,SDWebImage的问题

需要在Appdelegate中设置一下

[[SDImageCache sharedImageCache] setShouldDecompressImages:NO];

[[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:NO];

[[SDImageCache sharedImageCache] setShouldCacheImagesInMemory:NO];

9、VM:CoreAnimation

Found out that animation caused by the inner pages.

Inside the pageViewController(viewController that added to the scrollView as a page) on viewWillDisappear:(BOOL)animated method I added this

for (CALayer* layer in [self.view.layer sublayers]) {

        [layer removeAllAnimations];

}

it resolved the problem.

10、@property (readwrite, nonatomic, copy) NSMutableURLRequest *request;出现Property of mutable type 'NSMutableURLRequest' has 'copy' attribute; an immutable object will be stored instead,解决方案

@property (readwrite, nonatomic, strong) NSMutableURLRequest *request;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容

  • 一. 视图控制对象通过alloc和init来创建,但是视图控制对象不会在创建的那一刻就马上创建相应的视图,而是等到...
    iOS菜鸟攻城狮阅读 605评论 0 7
  • 1. 用ARC管理内存 ARC(Automatic ReferenceCounting, 自动引用计数),它避免了...
    anyurchao阅读 2,824评论 0 16
  • 简述: 本应释放的内存没有释放,导致可用空间减少的现象。举个例子:你dismiss了一个视图控制器,但是最终却没有...
    iOS_肖晨阅读 2,706评论 2 62
  • 1. 避免内存泄漏 ① 避免对象之间循环引用(代理一定要弱引用)② block 中对象的循环引用、添加的通知在销毁...
    Install_be阅读 166评论 0 0
  • 问题1:多个页面无法成功dealloc,内存没有被释放.界面的循环引用问题问题2:某页面成功dealloc,但是仍...
    zhangwenqiang阅读 251评论 0 1