OC语言之内存管理
来源:互联网 发布:千牛mac登不上去 编辑:程序博客网 时间:2024/05/17 22:28
一、引用计数器
每一个OC对象都有自己的引用计数器,是一个整数(4个字节),表示“对象被引用的次数”,当计数器为0的时候,对象就会被回收,对象回收的依据是对象的计数器是否为0。当对象刚刚产生的时候,计数器默认为1。
当使用alloc、new、copy创建一个对象时,新对象的引用计数器默认就是1。
字符串对象不需要release;
引用计数器的操作:
1.给对象发送一条retain消息,可以使引用计数器值+1(retain方法返回对象本身)
2.给对象发送一条release消息,可以使引用计数器值-1
3.可以给对象发送retainCount消息获得当前的引用计数器值
当对象引用计数器值为0时,对象就会被销毁,其所占的内存被系统回收;
当一个对象销毁时,系统会自动向对象发送一条dealloc消息;
一般会重写dealloc方法,在对象销毁时做一些操作(类似android中的onDestory);
重写dealloc方法,必须调用[super dealloc],并且放在最后调用。
僵尸对象:当对象的引用计数器为0时,此对象为僵尸对象(不可用内存)。
野指针:指向僵尸对象的指针为野指针,野指针再调用会报错,野指针错误
message sent to dealloced instance 0x……
僵尸对象检测开关:点击stop后边->点击“edit scheme”->点击“diagnostics”->“enable zombie objects”
int main(){Person *p = [[Person alloc] init];[p release];}
二、多对象内存管理
原则:谁创建(alloc、new、copy),谁release(或者autorelease);谁retain谁release
按照内存管理原则,set方法代码规范:
@implementation Person- (void)setBook:(Book *)book{//1.判断是不是新传进来的对象if(book != _book){//2.对旧对象做一次release[_book release];//3.对新对象做一次retain_book = [book retain];}}
dealloc方法代码规范:
1.一定要[super dealloc],而且放到最后面
2.对self(当前)所拥有的其他对象做一次release
- (void)dealloc{[_book release];[super dealloc];}
property参数:
1.set方法内存管理相关参数
retain:release旧值,retain新值(适用于oc对象类型)
assign:直接赋值(默认,适用于非oc对象类型)
copy:release旧值,copy新值
2.是否要生成setter方法
readwrite:同时生产setter和getter的声明、实现(默认)
readonly:只会生成getter的声明、实现
3.多线程管理
nonatomic:性能高(一般就用这个)
atomic:性能低(默认)
4.setter和getter方法的名称(一般用在bool类型“@property(getter = isRich) BOOL rich;”)
setter:决定set方法的名称,一定要有个冒号
getter:决定get方法的名称
@class的使用:
1.@class的作用:仅仅告诉编译器,某个名称是一个类
@class Person; //仅仅告诉编译器,Person是一个类
2.开发中引用一个类的规范
1>在.h文件中用@class类声明类
2>在.m文件中用#import来包含类的所有东西
3。两端循环解决方案:
1>一端用retain
2>一端用assin
三、autorelease(since ios5.0)
1.autorelease基本用法
1>autorelease会将对象放到一个自动释放池中
2>当自动释放池呗销毁时,会对池子里的所有对象做一次release操作
3>autorelease方法会返回对象本身
4>调用完autorelease方法后,对象的计数器不变
2.autorelease的好处
1>不用再关心对象释放的时间
2>不用再关心什么时候调用release
3.autorelease的使用注意
1>占用内存较大的对象不要随便使用autorelease,要使用release对对象进行精确控制
2>占用内存较小的对象没有太大影响
@autorealeasepool
{//大括号开始代表创建了释放池
Person *p =[[[Person alloc] init] autorelease];
p.age = 10;
}//大括号结束代表销毁释放池
1>自动释放池存放在栈中,先进后出原则;最先创建的池子放在栈的最底部,最上边的池子最先销毁。
2>当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池
autorelease错误写法:
1.调用autorelease后又release
2.连续调用两次autorelease(池子销毁时会对对象进行两次release,野指针错误)
autorelease前身:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];// 之前的代码会在pool调用release后释放。因为调用autorelease后会将对象放到栈顶的释放池里,此时栈内存只有pool这个释放池,所以是放在了这个pool中
Person *p = [[[Person alloc] init] autorelease];
[pool release];
快速创建一个已经autorelease过的对象:
在类方法中封装autorelease,创建对象时不要直接用类名,一般用self
+ (id)person{return [[[self alloc] init] autorelease]; // self的好处是,满足子类调用需求,返回的是调用类型的对象}+ (id)personWithAge:(int)age{Person *p = [self person];p.age = age;return p;}int main(){@autoreleasepool{//Person *p = [Person person];Person *p = [Person personWithAge:100];}}
*类方法代码规范,类方法以类名开头。
*系统自带的方法里没有包含alloc、new、copy,说明返回的对象都是autorelease的
*开发中经常会提供一些类方法,快速创建一个已经autorelease过的对象
三、ARC
ARC判断准则:只要没有强指针指向对象,就会释放对象
指针分两种:
1>强指针:默认情况下,所有的指针都是强指针 __strong
2>弱指针:__weak
当对象没有强指针指向时,会释放对象,同时清空弱指针(防止野指针的情况出现)。
ARC特点
1>不允许调用release、retain、retainCount
2>允许重写dealloc,但是不允许调用[super dealloc]
3>@property的参数
*strong:成员变量是强指针,相当于原来的retain(适用于OC对象类型)
*weak:成语变量是弱指针,相当于原来的assign(适用于OC对象类型)
*assign:适用于非OC对象类型
ARC转换功能:
非ARC转ARC:Edit->Refactor->Convert to Objective-C ARC(或者文件做标记“-f-objc-arc”)
ARC查看:点击项目->Build Settings->搜索“Automatic”->Objective-C ARC 标记为yes
ARC转非ARC:点击项目->Build Phases->Complle Sources->双击文件做标记“-fno-objc-arc”
ARC项目,解决循环引用:
一端用strong
一端用weak
- OC语言之内存管理
- OC语言之内存管理简介
- OC之内存管理
- OC之内存管理
- OC之内存管理
- OC之内存管理
- OC之内存管理
- OC之内存管理
- OC之内存管理
- oc之内存管理
- OC学习心得之内存管理
- 黑马程序员-----oc语言学习笔记之内存管理一
- 黑马程序员-----oc语言学习笔记之内存管理二
- 黑马程序员-----oc语言学习笔记之内存管理三
- C语言之内存管理
- C语言之内存管理
- C语言之内存管理
- C语言之内存管理
- 搭建一个免费的,无限流量的Blog----github Pages和Jekyll入门
- poj1691 Painting A Board(DFS+拓扑)
- 查找附近网点geohash算法及实现 (Java版本)
- Linux命令行下的文本编辑器
- 获得已安装软件的签名信息
- OC语言之内存管理
- js 文章列表li 分页
- linux mmap函数详解
- Attempted to lock an already-locked dir异常解决方法
- iOS 中的 va_list\va_arg\va_start和va_end的使用
- APK安装过程及原理详解
- java学习笔记8 - maven profile实现多环境打包
- iOS 汉子转拼音 按首字母排序
- Android学习笔记——OAuth完全手册_国内篇