IOS内存管理学习笔记
内存管理作为iOS中非常重要的部分,每一个iOS开发者都应该深入了解iOS内存管理,最近在学习iOS中整理出了一些知识点,先从MRC开始说起。
1.当一个对象在创建之后它的引用计数器为1,当调用这个对象的alloc、retain、new、copy方法之后引用计数器自动在原来的基础上加1(ObjC中调用一个对象的方法就是给这个对象发送一个消息),当调用这个对象的release方法之后它的引用计数器减1,如果一个对象的引用计数器为0,则系统会自动调用这个对象的dealloc方法来销毁这个对象。
2.@property的参数可以分为三类,也就是说最多可以有三个参数,参数的含义如下表:
|
参数类型 |
参数名 |
参数含义 |
|
原子性 |
atomic |
对属性加锁,线程安全,默认属性 |
|
nonatomic |
不加锁,非线程安全 |
|
|
读写属性 |
readonly |
生成getter和setter方法,默认属性 |
|
readwrite |
只生成getter方法 |
|
|
set方法处理 |
assign |
直接赋值,默认值 |
|
retain |
先release原来的值,再retain新值 |
|
|
copy |
先release原来的值,再copy新值 |
各种属性对应的setter方法内容如下:
assign, 通常用于基本数据类型,如:int,float
-(void)setA:(int)a{
_a=a;
}
retain,通常用于非字符串对象
-(void)setA:(A *)a{
if(_a!=a){
[_a release];
_a=[a retain];
}
}
copy,通常用于字符串对象,block,NSArray,NSDictionary
-(void)setA:(NSString *)a{
if(_a!=a){
[_a release];
_a=[a copy];
}
}
3. 当使用手动引用计数的时候,Fundation框架中的一些方法可能会增加对象的引用计数,比如NSMutableArray中的addObject或者UIView中的addSubview,有一些方法将会减少对象的引用计数比如上面两个接口对应的removeObjectAtIndex和removeFromSuperview。
4.再创建对象的时候推荐使用[[className alloc]init]而不是[className new],因为如果使用[className new],内部是调用的init方法初始化,我们就没法调用initWithFrame之类的方法。
5.alloc:对象分配后引用计数为1,retain:对象的引用计数+1,copy:开辟新的内存存放新对象,引用计数为1,原对象引用计数不变。
6.给对象发送release消息并不一定会销毁这个对象,而是将对象的引用计数-1,如果对象的引用计数为0的话,对象就会被销毁。然后系统会发送dealloc消息给这个对象释放它的内存。
7.对使用了retain、copy、mutableCopy、alloc、new方法的任何对象,以及具有retain和copy特性的属性进行释放,需要覆盖dealloc方法,使得在对象被释放的时候能够释放这些实例变量。
8.NSAutoreleasePool内部包含一个数组(NSMutableArray),用来保存声明为autorelease的所有对象。如果一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中去。
ClassA *obj1 = [[[ClassA alloc] init] autorelease]; //retain count = 1,把此对象加入autorelease pool中
NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数组,release数组中的每个成员。如果此时数组中成员的retain count为1,那么release之后,retain count为0,对象正式被销毁。如果此时数组中成员的retain count大于1,那么release之后,retain count大于0,此对象依然没有被销毁,内存泄露。如果再方法中不需要再使用这个对象,但是需要将其返回,可以向这个对象发送autorelease消息将其放入到自动释放池用以标记这个对象延迟释放,autorelease并不会影响到对象的引用计数。
ClassA *Func1()
{
ClassA *obj = [[[ClassA alloc]init]autorelease];
return obj;
}
当引用程序终止的时候,内存中所有的对象都会被释放,不论是否放入到自动释放池中。如果对对象比较大的话不建议放入到自动释放池中,因为自动释放池延迟释放会导致程序占用内存较多。在iOS程序中会创建许多的自动释放池,这些自动释放池都是以栈(先进后出)的形式进行管理的,比如有两个嵌套的自动释放池:
@autoreleasepool {
// 对象的释放交给 自动释放池去管理 不用再写[person release]
Person *person = [[[Person alloc] init] autorelease];
// 再创建一个自动释放池2
@autoreleasepool {
Person *person2 = [[[Person alloc] init] autorelease];
}
Person *person3 = [[[Person alloc] init] autorelease];
}
释放的顺序就是person2->person->person3,先释放内层的,再释放外层的,同一层的从上到下释放。
自从ARC出来之后,iOS开发内存管理便方便很多,总结要点如下:
1.__strong:表示引用为强引用。对应在定义property时的"strong"。所有对象只有当没有任何一个强引用指向时,才会被释放。如果属性前面不加修饰符,默认的引用方式就是强引用,当需要释放强引用指向的对象时,需要将强引用置nil。
2.__weak:表示为弱引用,弱引用不会影响到对象的释放,就算有一百个弱引用指向某个对象,对象依然会被释放(当没有任何一个强引用指向该对象的时候),但是当对象被释放之后,所有志向该对象的弱引用将会被置为nil。弱引用可以防止循环引用,比如delegate就是使用的弱引用。
3.__autoreleasing:表示在autorelease pool中自动释放对象的引用,和MRC时代autorelease的用法相同。定义property时不能使用这个修饰符,任何一个对象的property都不应该是autorelease型的。以下两行代码的意义是相同的。
NSString *str = [[[NSString alloc] initWithFormat:@"hehe"] autorelease]; // MRC
NSString *__autoreleasing str = [[NSString alloc] initWithFormat:@"hehe"]; // ARC
4.声明IBOutlet时一般应当使用weak,除了对StoryBoard这样nib中间的顶层对象要用strong
5.weak相当于老版本的assign,strong相当于retain,copy的作用和原来一样
6.不能直接调用dealloc方法,不能调用retain,release,autorelease,retainCount方法,包括@selector(retain)的方式也不行
7.可以用dealloc方法来管理一些资源,但不能用来释放实例变量,也不能在dealloc方法里面去掉[super dealloc]方法,在ARC下父类的dealloc同样由编译器来自动完成
IOS内存管理学习笔记的更多相关文章
- C++内存管理学习笔记(5)
/****************************************************************/ /* 学习是合作和分享式的! /* Auth ...
- C++内存管理学习笔记(6)
/****************************************************************/ /* 学习是合作和分享式的! /* Auth ...
- C++内存管理学习笔记(7)
/****************************************************************/ /* 学习是合作和分享式的! /* Auth ...
- C++内存管理学习笔记(4)
/****************************************************************/ /* 学习是合作和分享式的! /* Auth ...
- C++内存管理学习笔记(3)
/****************************************************************/ /* 学习是合作和分享式的! /* Auth ...
- C++内存管理学习笔记(2)
/****************************************************************/ /* 学习是合作和分享式的! /* Auth ...
- C++内存管理学习笔记(1)
/****************************************************************/ /* 学习是合作和分享式的! /* Auth ...
- Unity移动游戏加载性能和内存管理-学习笔记
前言 正在学习Doctor 张.鑫大佬的移动游戏加载性能和内存管理,内容非常非常的干,所以我烧了很多开水,边喝边看,一边拿小本几做好笔记 本文只是关于前2章的内容笔记,关于各种资源的加载耗时 纹理资源 ...
- Linux内存管理学习笔记 转
https://yq.aliyun.com/articles/11192?spm=0.0.0.0.hq1MsD 随着要维护的服务器增多,遇到的各种稀奇古怪的问题也会增多,要想彻底解决这些“小”问题往往 ...
随机推荐
- [ACM_几何] UVA 11300 Spreading the Wealth [分金币 左右给 最终相等 方程组 中位数]
Problem A Communist regime is trying to redistribute wealth in a village. They have have decided to ...
- 抢小米软件html版(简单有效)
地球人都知道小米性价比高,大家都很期待,但是抢小米却是一件很头疼的事. 本来抢的人就多,还有一些大牛.黄牛使用软件来抢,人家有成百上千台电脑,开上几万个线程,很难抢过人家... 小菜分享一款简单的小米 ...
- Linux下jvm、tomcat、mysql、log4j优化配置笔记
小菜一直对操作系统心存畏惧,以前也很少接触,这次创业购买了Linux云主机,由于木有人帮忙,只能自己动手优化服务器了.... 小菜的云主机配置大致为:centeos6(32位),4核心cpu,4G内存 ...
- atitit.二维码生成总结java zxing
atitit.二维码生成总结java zxing #-----zxing类库.. but zxing3.0 的类库core-3.0.jar 需要jdk7 只好zing2.2.jar ..jdk6走o ...
- paip.gui控件tabs控件加载内容的原理以及easyui最佳实现
paip.gui控件tabs控件加载内容的原理以及easyui最佳实现 //////////////tabs控件的加载 同form窗体一样,俩个方式 两个方式:一个是url,简单的文本可以使用这个,不 ...
- PHP--------memcache技术
新事物的产生都不是偶然的 1.为什么会产生memcache? 在大型的电商web页面上,数据量庞大,大量用户需要同时访问海量的数据,为了提高用户的访问效果,如何才能让页面加载最快,更友好的展示到用户面 ...
- 详解Bootstrap进度条组件
在网页中,进度条的效果并不少见,如:平分系统.加载状态等,进度条组件使用了css3的transition和animation属性来完成一些特效,这些特效在IE9及IE9以下版本.Firefox的老版本 ...
- python ide: pycharm
1, 设置python路径 2,运行py文件 https://www.jetbrains.com/help/pycharm/2016.1/creating-and-running-your-first ...
- 深入学习golang(2)—channel
Channel 1. 概述 “网络,并发”是Go语言的两大feature.Go语言号称“互联网的C语言”,与使用传统的C语言相比,写一个Server所使用的代码更少,也更简单.写一个Server除了网 ...
- 利用Android Studio、MAT对Android进行内存泄漏检测
利用Android Studio.MAT对Android进行内存泄漏检测 Android开发中难免会遇到各种内存泄漏,如果不及时发现处理,会导致出现内存越用越大,可能会因为内存泄漏导致出现各种奇怪的c ...