【自动释放池】
[autorelease方法和自动释放池]
每一个对象都有一个autorelease方法,调用autorelease方法之后不会像调用release方法一样马上释放对象,
当一个对象调用一个autorelease的时候,这个对象就会被放倒main函数开始时设置的自动释放池里
当整个函数执行完毕之后,autoreleasepool才会销毁,销毁时把自己内部所有的对象全部释放掉,方式就是对所有的对象都执行一次release。
它和对象在哪里创建的没有关系,只要执行autorelease方法即可实现自动释放池
调用几次autorelease方法就往自动释放池里放几次,在自动释放池销毁的时候就会销毁几次
[自动释放池的嵌套]
自动释放池可以实现一个栈的结构,一个自动释放池中可以包含另一个自动释放池
[自动释放池的原理]
1、系统中有一个自动释放池栈,当程序运行到一个@autoreleasepool{}时,就会把当前的autoreleasepool压入栈中,在退出的时候,也是后进先出
2、当遇到与之对应的}时,自动释放池出栈,出栈的时候会对池中所有的对象进行一次releease操作
3、自动释放池栈中只有栈顶的自动释放池是活动的,其他的都在休眠
4、当调用autorelease的时候,会把这个对象放到栈顶的那个自动释放池中
[自动释放池的使用场景]
总的来说一句话,只要是从方法中返回出来的对象,方法中都需要在返回对象之前调用自动释放池
(1)、getter方法里返回对象
当要通过普通的方法来返回成员对象给外面的时候,外面不需要对获得到的这个成员对象进行内存管理,这时候外面就需要使用自动释放池保护相关操作,并在成员对象的getter函数中应该使用如下写法
用法:
先retain
再autorelease
其实就是autorelease延长了生命周期
(2)、类方法中创建自身对象(快捷构造方法)
其实所有的NS开头的构造方法内部都调用了autorelease
[成员对象赋值时进行的操作]
因为成员对象是一个对象,所以就会有引用计数,在赋值成员对象的时候应该先释放掉旧的对象(调用release将旧对象的引用计数-1),然后赋值给类成员新的对象(调用retain将新对象的引用计数+1)
【手动内存管理】
在手动内存管理的时候(关闭了自动内存管理)
[手动内存管理的关键字]
@property (retain) Room *room;
retain 在setter喝getter方法中加入一些内存管理代码
当属性是一个普通的OC对象的时候,使用retain
[MRC中的@property]
@property (assign) int age 
assign 直接赋值,不生成内存管理的代码
基本数据类型是在栈内的,栈内的变量是不需要内存管理的
@property (copy) NSString *name
copy表示复制对象,NSString一般使用copy,其他的对象都使用retain
@property (nonatomic)int age
[生成多线程的线程安全关键字]
nonatomic:表示非原子的,不会生成线程安全的代码,速度会比较快,在ios中属性通常都是这种的。一般要把所有的关键字都写成nonatomic的
@property (readwrite) int age
[控制权限的关键字]
readonly:只读,不可写,只能生成getter方法
writeonly:只写,不可读,只能生成setter方法
readwrite:可读写,能生成getter和setter方法
[修改方法名称的关键字]
@property (getter = isMan, setter = myMan:)BOOL sex;
通过property 属性修改getter/setter方法的名称
这样使用的时候就可以调用
sex = 类名.isMan;
[p myMan:YES];
一般情况下都不修改setter和getter方法
(5)关键字的组合方法
多个属性之间可以这样组合
@property (atomic, assign)int age;

【自动内存管理】
ARC机制可以帮我们解决所有的内存问题 
这是一种编译器特性,编译器会在适当的时候加入内存管理代码
当打开了自动内存管理时,在代码中不允许写内存管理的操作
我们可以写一个dealloc,但是在dealloc中一定不能写[super dealloc],因为编译器已经自动添加了
[强指针 弱指针]
强指针:默认所有指针都是强指针
只要有强指针一个对象,这个对象就不会被释放
如果没有强指针指向一个对象,这个对象就会被立即回收
例子
如果一个对象只有一个指针指向,那么如果这个指针不指向这个对象,对象就立即死了
出了作用域之后,指针也会被释放(栈自动回收)
__strong就是强指针的标示,默认所有的指针都是强指针,所以没卵用
弱指针指向的对象不会影响对象的回收
__weak时弱指针的标示,如果在对象创建的时候用弱指针接收的话,那么就该对象在创建后直接就被杀死了,所以不要用弱指针指向一个刚刚创建出来的对象
弱指针的作用
在自动内存管理的时候会有循环引用的问题,在其中的一个对象指针上使用弱指针就能解决循环引用的问题
例如
人里有狗,狗里有人
这种情况就会产生循环应用的问题
人会管理狗的生命周期
狗不会管理人的生命周期
所以狗中的人成员对象就应该设置为弱指针
当多个对象之间的引用构成一个环,则这个环中所有指针都不会被释放掉,只有其中的一个成员对象是弱指针,才能顺利的释放
[ARC中的@property]
在ARC中,使用@property的时候一般
对基本数据类型使用nonatomic和assign
对字符串数据类型使用nonatomic和copy
对对象数据类型使用nonatomic和strong/weak
其中weak是为了防止循环引用,像在Dog类中的person对象这样的需要使用weak,一般对象都是strong
例:
@property (nonatomic, assign) int age;
@property (nonatomic, copy) NSString *name;
@property (nonatomic,strong) CZDog *dog;
解释:assign:对该成员赋值时不改变引用计数
 copy:对该成员赋值时释放旧的对象保持新对象引用计数为1
strong:强指针
weak:弱指针
[instancetype]
instancetype可以检查类型,并且只能作为返回值类型,其他什么都不能做
[ARC中的自动释放池]
方法创建的对象被放在自动释放池中,即使没有强指针指向方法创建出来的对象,这个对象也不会被立即释放。
方法返回的对象,可以在没有强指针指向的情况下存活于自动释放池中
但是这里说的方法不包括alloc,alloc是比较特殊的,它返回的对象没有执行放进自动释放池的操作
[由自动释放池引出的关于构造函数的思考]
所以这就解释了为什么alloc出来的指针是中间指针,而最后返回的指针是init前缀的构造方法产生的指针
因为init前缀的构造方法都是工厂方法,工厂方法里肯定会执行三步操作
第一步:释放self(释放调用此init工厂方法的本对象)
第二步:创建新对象(创建一个新的对象接收传入的初始化值)
第三步:对接收完的新对象进行autorelease操作
第四步:返回新对象给一个强指针
[引用计数增加的情况]
强指针指向,+1
跳出作用域,-1
赋值nil, -1
autoreleasepool的边界右括号,-1
【自动释放池的一道面试题】
autoreleasepool{
for(long i = 0; i < NSIntegerMax; i++)
{
NSString *str = [NSString stringwithFormat:@“dawd”];
str = [str uppercaseString];
str = [str lowercaseString];
str = [str capitalizedString];
}
}
问题出在使用这个方法[NSString stringwithFormat:@“dawd”];创建出来的对象释放在自动释放池中的,但是for循环一直处于自动释放出中,所以就一直不释放,解决办法如下:
autoreleasepool{
for(long i = 0; i < NSIntegerMax; i++)

{

autoreleasepool{

NSString *str = [NSString stringwithFormat:@“dawd”];

str = [str uppercaseString];

str = [str lowercaseString];

str = [str capitalizedString];

]

}

}
PS:这个操作会导致CPU满载,另外每一个项目都都要注意内存和CPU的占用问题
[OC的ARC特点]
OC的ARC是编译器特性,不是运行时特性,java是运行时检测那个对象需要被释放,所以效率低
但是oc是编译的时候由编译器自动添加内存管理代码,所以不会对效率产生任何影响
【经典的循环引用问题】
person包含dog
dog也包含person
如果全部都加上手动内存管理的情况下,则每一个对象的引用计数都是2,则在程序结尾调用release后,都为1,则互相之间都释放不了
MRC解决方法(使用retain/assign):将其中任一一个应用其他对象的成员,在定义的时候设置assign关键字,即赋值给这个成员对象的时候不会增加引用计数
多个对象之间成环引用的情况的解决方法也是一样的,只要把任一成语对象引用设置为assign即可
ARC解决方法(使用strong/weak):将其中任一一个应用其他对象的成员,在定义的时候设置weak关键字,即赋值给这个成员对象的时候不会增加引用计数
多个对象之间成环引用的情况的解决方法也是一样的,只要把任一成语对象引用设置为weak即可

IOS第四节:OC中的内存管理机制相关推荐

  1. C++中运行一个程序的内存分配情况及qt中的内存管理机制

    一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) - 一 ...

  2. 【精华】详解Qt中的内存管理机制

    前言 内存管理,是对软件中内存资源的分配与释放进行有效管理的方法和理论. 众所周知,内存管理是软件开发的一个重要的内容.软件规模越大,内存管理可能出现的问题越多.如果像C语言一样手动地管理内存,一会给 ...

  3. 黑马程序员--Objective-C之--OC中的内存管理

    ------IOS培训期待与您交流! ------- 对于面向对象的变成语言,程序需要不断地创建对象. 初始,创建的所有程序通常都有指针指向它,程序可能需要访问这些对象的实例变量或调用这些对象的方法, ...

  4. Python中的内存管理机制

    Python是如何进行内存管理的 python引用了一个内存池(memory pool)机制,即pymalloc机制,用于管理对小块内存的申请和释放 1.介绍 python和其他高级语言一样,会进行自 ...

  5. 简述python中的内存管理机制_Python中的内存管理机制

    Python是如何进行内存管理的 python引用了一个内存池(memory pool)机制,即pymalloc机制,用于管理对小块内存的申请和释放 1.介绍 python和其他高级语言一样,会进行自 ...

  6. Linux驱动学习--android中的内存管理机制ION(一)--简单介绍

    目录 一.引言 二.ION的介绍及使用 ------> ION介绍 ------> ION的使用 ------> HEAP种类 三.接口分析 ------> 主要数据结构 -- ...

  7. Linux驱动学习--android中的内存管理机制ION(二)--ION的使用

    目录 一.引言 二.ION框架 ------> heap类型 ------> ion特性 三.ion的使用 ------> 基本数据结构 ------> 具体的使用 四.ion ...

  8. 【iOS开发-35】有了ARC内存管理机制,是否还须要操心内存溢出等问题?——面试必备...

    答案:必需要操心啊,ARC也不是万能的. 这里主要是涉及到集合类的数据类型. 比方数组,我们定义了一个可变数组muarr1,然后把一个对象p1加到muarr1中,此时会对这个对象retain一次,相当 ...

  9. python中画糖葫芦的代码_Python中的内存管理

    内存管理 包括: ①变量无须事先声明,变量无须指定类型 ②引用计数 ③垃圾回收 ④内存池机制 ①变量定义 不用事先声明变量类型而直接对变量进行赋值.对Python语言来讲,对象的类型和内存都是在运行时 ...

最新文章

  1. 【字节流处理】linux下uint8转float的注意事项
  2. Perl正则表达式匹配
  3. 手动卸载_一种手动液压一体式卸载扳手
  4. springboot 物联网_Confluent Kafka,KSQL,Spring Boot和分布式SQL开发物联网实战
  5. PyTorch学习—20.模型的微调(Finetune)
  6. shell之文本过滤(awk)(转)
  7. 谈谈大型分布式网站架构技术总结
  8. 4、wpf 打包为exe或者msi的安装程序
  9. 微信聊天内容制作生成器微信小程序源码_支持多种制作生成
  10. 小白网安学习日记(2) hacknet游戏(模拟黑客入侵的游戏)
  11. stm32f103c6t6
  12. jbox弹窗_强大的jquery弹出层插件jBox
  13. 文字盘点:当今社会十句最恶俗的流行书面中文
  14. 富有创意的电子邮件签名设计(Email signature creative design template)
  15. 英语月份、星期、日期的缩写
  16. 腾讯Hardcoder Android通讯框架简介
  17. python合并json_组合两个json字典python
  18. 墨云saas系统总结
  19. 2022高教社杯数学建模思路 - 复盘:中小微企业的信贷决策
  20. 人生中第一次面试-----字节跳动面试经验总结

热门文章

  1. C# showDialog()
  2. less 命令用法详解
  3. 率土之滨显示没选择服务器,率土之滨 这些实用攻略还不知道你就OUT啦
  4. Python设置画布大小_turtle.screensize改变不了窗口大小?
  5. time lapse-----延时摄影
  6. 使用蓝叠模拟安卓系统安装apk文件
  7. 全球及中国自拍环形灯行业市场需求及未来竞争动向展望报告2022-2027年
  8. 快速安装Docker详细图文步骤教程
  9. 茶杯大小的狗狗,看一眼整个人都酥了!
  10. 闪耀暖暖服务器维护,闪耀暖暖服务器地址失败怎么办