iOS另类的内存管理
2016-04-14 10:39
225 查看
好久没有更新自己的博客了, 哎!!! 国庆七天小长假就这样没了,
有没有和我一样的小伙伴一回来就开始忙碌的搬砖呢, 今天正好也不是很忙, 就抽空写点东西吧..
今天就合大家扯扯iOS的内存管理吧,
大家都明白iOS的内存管理有两种方式 一种是arc 另一种是marc
废话不多说了 直接搞起
iOS的内存管理算是老生常谈的问题了,我们写iOS的时候无时无刻不在涉及到内存管理。从开始的MRR(manual
retain-release)到后来ARC(Automatic Reference
Counting),包括CoreFoundation的内存管理都遵守引用计数的基本原则。
基本的内存管理大家肯定都很熟悉,在这里主要说一点,其余的就不多说了。官方文档有这样的一段话
You create an object using a method whose name begins with “alloc”,
“new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or
mutableCopy).
大意就是说,如果你使用alloc/new/copy/mutableCopy这些开头的方法创建了一个对象,那么你就会拥有这个对象(retain)。当你不用的时候,你就需要手动的去release一次。
举一个例子,假设有一个方法,
我们应该这么使用,如果我们最后不release,就会导致Object被泄漏。
[Method-MRR]
既然这样的话,我们也可以想象出如果我们要自己实现new开头的方法,我们需要如下代码
[Method-MRR]
那么就产生了以下几个问题:
MRR下实现了一个newObject方法,该方法遵守约定的原则,返回值会retain+1,然后在ARC下调用该方法创建对象
MRR下实现了一个newObject方法,该方法没有遵守约定原则,返回autorelease的对象,然后在ARC下调用该方法创建对象
ARC下实现了一个newObject方法,然后在MRR下调用newObject方法创建对象,使用完成之后release
ARC下实现了一个newObject方法,然后在MRR下调用newObject方法创建对象,使用完成之后没有release
我们可以自己编写以上的实验代码,然后测试。
最终测试结果如下:
场景1,3下运行正常
场景2下会crash
场景4下产生内存泄露
为什么场景2会crash呢?这是由于ARC下我们编译器如果看到你是以alloc/new/copy/mutableCopy等开头的方法创建了对象,则会在使用的最后插入一次release操作,由于返回的是autorelease的对象,又被release了一次,所以导致野指针。
场景4产生泄漏的原因也是一样,ARC下编译器发现该方法是new等开头的时候,方法结束的时候不会插入release语句,场景4使用的过程中,没有对newObject进行release,所以会产生泄漏。
如果我们仅使用MRR或者ARC的话,这种问题一般不会出现。这种问题的出现一般是当ARC/MRR混编的时候,由于一些编写的不规范导致的,所以在写代码的过程中,遵守规范是很有必要的。
如果我们自己编写alloc/new/copy/mutableCopy开头的方法的时候,MRR下一定不要忘了返回retain的对象,同样当我们使用alloc/new/copy/mutableCopy的方法创建对象的时候,也不能忘了在用完之后release。
如果我们有一段MRR的代码,提供了一个new开头的方法但是没有遵守规范,我们ARC下该怎么办呢?按照上面的结论,我们正常使用肯定会导致野指针的
在这里呢,如果能改代码当然把代码都改成遵守规范的最好,如果不能改源码的话,我们只能修改使用方。在这里提供一种方法:
[Method-ARC]
大家可以尝试一下,然后思考一下为什么。
关于iOS的内存管理远远不止这些,本文中说的大家实际编码的过程中也很少遇到,仅仅当作知识的补充吧~
有没有和我一样的小伙伴一回来就开始忙碌的搬砖呢, 今天正好也不是很忙, 就抽空写点东西吧..
今天就合大家扯扯iOS的内存管理吧,
大家都明白iOS的内存管理有两种方式 一种是arc 另一种是marc
废话不多说了 直接搞起
iOS的内存管理算是老生常谈的问题了,我们写iOS的时候无时无刻不在涉及到内存管理。从开始的MRR(manual
retain-release)到后来ARC(Automatic Reference
Counting),包括CoreFoundation的内存管理都遵守引用计数的基本原则。
基本的内存管理大家肯定都很熟悉,在这里主要说一点,其余的就不多说了。官方文档有这样的一段话
- You own any object you create
You create an object using a method whose name begins with “alloc”,“new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or
mutableCopy).
大意就是说,如果你使用alloc/new/copy/mutableCopy这些开头的方法创建了一个对象,那么你就会拥有这个对象(retain)。当你不用的时候,你就需要手动的去release一次。
举一个例子,假设有一个方法,
[STObject newObject]
我们应该这么使用,如果我们最后不release,就会导致Object被泄漏。
[Method-MRR]
1 2 3 | [code]STObject *object = [STObject newObject]; // do something [object release]; [/code] |
既然这样的话,我们也可以想象出如果我们要自己实现new开头的方法,我们需要如下代码
[Method-MRR]
1 2 34 | [code]- (instancetype)newObject { return [[[self class] alloc] init]; } + (UIButton *)copyButton { return [[UIButton buttonWithType:UIButtonTypeCustom] retain]; } [/code] |
MRR下实现了一个newObject方法,该方法遵守约定的原则,返回值会retain+1,然后在ARC下调用该方法创建对象
MRR下实现了一个newObject方法,该方法没有遵守约定原则,返回autorelease的对象,然后在ARC下调用该方法创建对象
ARC下实现了一个newObject方法,然后在MRR下调用newObject方法创建对象,使用完成之后release
ARC下实现了一个newObject方法,然后在MRR下调用newObject方法创建对象,使用完成之后没有release
我们可以自己编写以上的实验代码,然后测试。
最终测试结果如下:
场景1,3下运行正常
场景2下会crash
场景4下产生内存泄露
为什么场景2会crash呢?这是由于ARC下我们编译器如果看到你是以alloc/new/copy/mutableCopy等开头的方法创建了对象,则会在使用的最后插入一次release操作,由于返回的是autorelease的对象,又被release了一次,所以导致野指针。
场景4产生泄漏的原因也是一样,ARC下编译器发现该方法是new等开头的时候,方法结束的时候不会插入release语句,场景4使用的过程中,没有对newObject进行release,所以会产生泄漏。
如果我们仅使用MRR或者ARC的话,这种问题一般不会出现。这种问题的出现一般是当ARC/MRR混编的时候,由于一些编写的不规范导致的,所以在写代码的过程中,遵守规范是很有必要的。
如果我们自己编写alloc/new/copy/mutableCopy开头的方法的时候,MRR下一定不要忘了返回retain的对象,同样当我们使用alloc/new/copy/mutableCopy的方法创建对象的时候,也不能忘了在用完之后release。
如果我们有一段MRR的代码,提供了一个new开头的方法但是没有遵守规范,我们ARC下该怎么办呢?按照上面的结论,我们正常使用肯定会导致野指针的
在这里呢,如果能改代码当然把代码都改成遵守规范的最好,如果不能改源码的话,我们只能修改使用方。在这里提供一种方法:
[Method-ARC]
1 2 | [code]SEL selector = NSSelectorFromString(@"copyObject"); STObject *object = (STObject *)[STObject performSelector:selector]; [/code] |
关于iOS的内存管理远远不止这些,本文中说的大家实际编码的过程中也很少遇到,仅仅当作知识的补充吧~
相关文章推荐
- iOS开发之自动化打包流程
- 友盟iOS统计中破解和越狱是什么?
- iOS开发之判断字符串是否为空的方…
- iOS延迟加载
- [iOS常见问题] 关于使用QQ做…
- iOS - AFNetworking2安…
- iOS presentViewController弹…
- iOS7返回手势的开启与禁用
- IOS中通知中心(NSNotificationCenter)的使用
- iOS 获取手机码时间倒计时(定…
- iOS多线程GCD
- iOS中延时执行的几种方式的比较和…
- IOS之同步请求、异步请求、GET请求…
- iOS view被导航条遮挡
- ios runtime 交换方法实现
- iOS 多线程 (GCD,Operation,Runloop)
- iOS开发中tableView的分割线的处理问题
- Block的基本使用
- iOS: 属性声明strong和retain竟然不一样
- ios开发中报错处理--include of non-modular header inside XXXX