内存管理
objective-c提供了第两种内存管理方式:manual retain-release(MRR,手动管理内存),automatic refrence counting (ARC ,自动引用计数)
内存管理的目的:
1、 不要释放还或者覆盖还在使用的内存,这样会引起程序崩溃
2、 释放不再使用的内存防止内存泄露
MRC也是基于引用计数的,只是通过开发者手动向某内存块发送消息来改变该内存块的引用计数。
ARC则是编译器代替开发者来完成相应地引用计数。
Objective-c中内存管理的应该遵循的规则:
1、谁创建谁release(包括:alloc,new,copy引用计数加1;NSArray的copy方法不能视为创建,引用计数不会加1)
2、谁想占有某个对象,谁就必须做retain操作
3、谁retain,谁release
4、解决两个对象相互引用的问题:
arc之前,可以一端使用retain,另一端使用assign;arc之后,一端使用strong,另一端使用weak
如何判断一个对象的销毁:
重写dealloc方法;
类别扩展
类别(GateGory):可以为现有的类添加新方法,而不需要继承。类别中的方法可以被子类继承。类别无法添加实例变量。相当于提供了一些接口,谁使用谁实现。
类别的声明:
@interface 类名(类别名)
@end
类别的作用:
1、 为现有的类添加新方法
2、 将类的实现分散到多个不同的文件或不同的框架中(把一个类按功能划分成几块,便于维护)
3、 创建对私有方法的前向应用
4、向对象添加非正式协议
类扩展:是没有类别名的类别。可以有实例变量
@interface 类名()
@end
正式协议与非正式协议:
正式协议就是我们通常的协议
非正式协议是使用CateGory来实现的,非正式协议是NSPObject的一个类别,这样任何类的对象都可以作为委托对象来使用,能够列出对象能使用的所有方法。
堆:(1)需要程序员自己管理
(2)oc中的对象保存在堆中
(3)内存管理不当造成的两个问题:
1>内存泄露:不在需要的对象没有释放,导致内存泄露,内存泄露会导致应用闪退。
2>野指针:正在使用的对象被释放了,导致野指针,访问野指针导致程序崩溃。
(4)MRC手动内存管理:
1>引用计数
一、每一个对象上都有一个引用计数器;
二、当对象出生的时候引用计数器为1;
三、当调用对象的retain方法时候计数器+1;
四、当给对象发送一条release消息的时候,计数器-1;
五、当一个对象的引用计数为0的时候,这个对象立即被回收;
2>内存管理原则
一、谁给一个对象发送alloc,copy,retain消息,就必须在适当时候给这个对象发送相应的release或autorelease消息。
二、当你需要一个对象的时候就给这个对象的引用器+1,当你不在需要这个对象了,就将这个对象引用计数器-1。
3>多个对象内存管理
一、setter方法:
1、当设置新对象的时候需要对新对象做一次retain操作;
2、当原来的对象不需要了,需要对原来的对象做一次release操作
3、如果是同一个对象不需要上面的操作。
二、dealloc方法:
1、当一个对象即将被销毁的时候会调用这个方法;
2、它就相当于对象的遗言,在这里释放其成员所占用的内存;
3、在释放内存之前首先要调用[super dealloc]
三、循环引用:
1、循环引用的概念:当两个或对个对象间的引用构成一个封闭的环就是循环引用。
2、循环引用导致的问题:环中的所有对象都释放不了。
3、循环引用的解决方案:有一端必须是assign的。
四、@property的使用:
1、内存管理 :(1)基本数据类型使用assign;
(2)普通对象一般使用retain;
(3)NSString及block对象使用copy;
(4)循环引用一端使用strong,一端使用assign;
2、权限控制:
readonly 只读仅生成getter方法;
readwrite 读写生成getter方法和setter方法;
3、线程安全:
atomic 线程安全的,会给setter方法加锁,访问速度比较慢
noatomic 非线程安全的,不会给setter方法加锁,访问速度快
4、方法名称定制:
setter 定制setter方法名称
getter 定制getter方法名称
五、自动释放池:
1、作用:延迟对象的释放
2、原理:自动释放池栈
3、使用:(1)当你调用autorelease的时候会把该对象放到例你最近的自动释放池中。
(2)当执行到自动释放池后面的大括号的时候,自动释放池会出栈,此时会把该栈中的所有的对象做一次release操作。
(3)你调用了几次autorelease,当自动释放池被销毁的时候就会调用几次release。
4、优点:你不必时刻关注对象的释放,让内存管理变的简单
5、缺点:对象不能及时的得到释放,如果对象占用内存很大,使用它会导致你程序闪退。
6、使用场景:
(1)当一个对象很小,使用次数比较少的时候可以使用自动释放。
(2)当一个对象占用内存比较大的时候不需要使用自动释放出。
(3)快捷构造方法。
(4)其他需要延长对象生命周期的地方。
(5)ARC自动引用计数
一、自动引用计数的概念:他是编译器特性,不是运行时特性;编译器会在适当的时候插入内存管理的代码。
二、强指针:1、默认所有的指针都是强指针
2、只要有强指针指向这个对象,这个对象就不会被销毁。
3、只要没有强指针指向这个对象,该对象立即会被销毁。
4、关键字:__strong
三、弱指针:1、弱指针不影响对象的销毁
2、关键字:__weak
四、循环引用:1、循环引用的简介:当多个对象间的引用出现环的时候就是循环引用。
2、循环引用的问题:环中的所有对象都是方法释放不了
3、解决方案:当出现循环引用的时候,一端必须使用__weak
五、@property的使用:
内存管理:1、assign 不参与内存管理,用于基本数据类型
2、strong 强引用:用于普通对象
3、copy 复制:用于字符串与block
4、weak 弱引用:防止循环引用
六、自动释放池:
1、通过类方法创建出来的对象都是放在离它最近的方法池中。
2、当自动释放池销毁的时候才能解除自动释放对该对象的引用。
栈:(1)内存由系统管理(2)局部变量保存在栈中(3)当变量离开了其所在的代码块就会被回收