您的位置:首页 > 移动开发 > IOS开发

iOS开发内存管理

2015-07-16 22:08 330 查看
说明:

1、计数器

2、@property的内存管理

3、循环语句

4、ARC

(一)内存管理

1、引用计数器的作用:

1> 当使用alloc、new或copy创建一个新对象时,新对象的引用计数器就认为是1,因此就必须调用[p release]/autorelease来使计数器-1;

2> 当一个对象的引用计数器值为0时,对象占用的内存就会被系统回收,若不为0,则在整个程序运行过程,它占用的内存就不可能被回收,除非整个程序已退出;

2、引用计数器的操作:

1> [p retain]:计数器+1(retain方法返回对象本身);【给对象发送一条retain消息可使引用计数器值+1】;

2> [p release]:计数器-1(release方法无返回值);【给对象发送一条release消息可使引用计数器值-1】;

3> [p retainCount]:获取当前计数器(%ld获取);【可给对象发送一条retainCount消息获得当前的引用计数器值】;

4> [super dealloc]:当一个对象要被回收时,一定放最后面调用;

3、对象的销毁:

1> 当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存会被系统回收;

2> 当一个对象被销毁时,系统会自动向对象发送一条dealloc对象;

3>

4、引用计数器

1> retain、release的基本使用:

① retain方法返回的是对象本身,计数器+1;([p retain];)

② release可使计数器-1;([p release]);

2> 野指针和空指针:

① 僵尸对象:所占用内测已被回收的对象,僵尸对象不能再使用(不能再调用[p retain],会报野指针错误);

② 野指针:指向僵尸对象(不可用内存的计数器为0的对象)的指针;

③ 空指针(OC中无空指针错误;):没指向任何东西的指针(存储的东西是nil、nul、,0),给空指针发送消息不会报错;

④ EXC_BAD_ACCESS:访问了一块坏的内存(已被回收、不可用的内存),野指针错误;

3> 多对象内存管理

① 你想使用(占用)某个对象,就应让对象的计数器+1([p retain]);

② 你不想使用(占用)某个对象,就应让对象的计数器-1([p release]);

③ 谁[p retain],谁[p release];

④ 谁[[p alloc] init],谁[p release];

4>

5、访问成员变量:

1> 直接访问成员变量:_speed;

2> 直接访问成员变量:self->_speed;

3> get方法:self.speed;

3> get方法:[self speed];

6、内存管理代码规范:

1> 只要调用[[p alloc] init],就必须[p release]/autorelease;

2> set方法代码规范:

3> dealloc方法的代码规范(不要直接调用):

① 当一个对象被回收时,一定要[super dealloc],且放到最后面;

② 对self(当前)所拥有的其它对象做一次release;

7、@property的内存管理:

1> 对象类型:都使用@property (retain) Book * book;//retain:生成的set方法里,release旧值,retain新值===》上面6的set方法;

2> @property参数分类:

① 内测管理相关参数:

。retain:release旧值,retain新值(适用于OC对象);

。assign:直接赋值(默认,适用于非OC对象类型);

。copy:release旧值,copy新值;

② 是否要生成set方法:

。readwrite:同时生成setter和getter的声明和实现(默认);

。readonly:只会生成getter的声明和实现;

③ 多线程管理:

。nonatomic:性能高(一般用这个);

。atomic:性能低(默认,耗性能);

① setter和getter方法的名称(一般不修改,修改后2者都可调用,BOOL类型可修改isCar):

。setter=方法名:;//决定set方法的名称,一定要有个冒号;

。getter=方法名;//决定了get方法的名称(一般用在BOOL类型);

② 总结:

。OC对象类型:@property (nonatomic , retain) 类名 * 属性名;

。非OC对象类型:(基本数据类型:@property (nonatomic,assign) 类型名称 属性名);

。被retain过的属性,必须在dealloc方法中release属性:

1> 表示时间(从1970年1.1日00:00:00开始至此度过的秒):

8、模型设计

1> 单例模式:

① 设计原理:始终返回一个实例,即一个类始终只有一个实例;

2> 创建单例设计模式基本步骤:

① 声明一个单例对象的静态实例,并初始化为nil;

② 创建一个类的类方法,生成一个该类的实例,当且仅有这个类实例nil时,进行实例化;

③ 覆盖allocWithZone:方法,确保用户直接分配和初始化后,不会产生新的对象;

④ 实现NSCopying协议,覆盖release、autorelease、retain,retainCount方法,以确保单例的状态;

⑤ 在多线程环境中,注意使用@synchronized关键字,确定静态实例被正确和初始化;

9、循环retain和@class

1> @interface中,在@interface之前定义:@class Card;//@class表示仅仅告诉编译器card是一个类;

2> 开发中引用一个类的规范:

① 在.h文件中用@class来声明类;

② 在.m文件中用#import来包含类的所有东西;

3> @class与#import的区别:

① #import方式会包含被引用类的所有信息,包括被引用类的变量及方法;@class方式只告诉编译器在A.h文件中B *b只是类的声明,具体类里的消息不需知道,等文件真正用到时才去查看B类中的信息;

② 若多个文件中都#import了同一个文件或这些文件依次被#import,那么头文件稍有改动,后面引用到此文件的所有类将需重新编译一次,这样相对来看,效率比@class降低了;

③ 在.m实现文件中,若需引用到被引用类的实体变量或方法时,还需使用#import方式引入被引用类;

4> 两端循环引用解决方案(例:Person与Card):

① 一端用retain;

② 一端用assign;

10、autorelease延迟释放使用(占用内存较小时使用,因为不确定池子销毁时间,从而不能及时销毁):

1> autorelease方法的基本语法:

① [p autorelease]方法会返回对象本身;

② [p autorelease]会将对象放到一个自动释放池中;

③ 当自动释放池被销毁时,会对池子里的所有对象做一次[p release]操作;

④ 调用完autorelease方法后,对象的计数器不变;

2> Autorelease使用的好处:

① 不用再关心对象释放的时间;

② 不用再关心什么时候调用release;

3> Autorelease的使用注意:

① 占用内存较大的对象不要随便使用autorelease;

② 占用内存较小的对象使用autorelease,没有太大影响;

4> 自动释放池:

① 创建自动释放池(Main函数中使用):

② 在iOS程序运行过程中,会创建无数个池子,这些池子都是以栈结构存在(先进后出);

③ 当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池;



5> 错误写法:

① alloc 之后调用了autorelease后,又调用release(如:Person *p=[[[Person alloc] init ] autorelease]; [p release];);

② 连续调用多次autorelease(如:Person *p=[[[[Person alloc] init ] autorelease] autorelease];);

6> autorelease使用规律:

① 系统自带的方法里面没有包含alloc、new、copy,说明返回的对象都是autorelese的(如:[NSString stringWithFromat:…]或[NSDaate date]…..);

② 开发中经常会提供一些类方法(以类名开头With成员变量:personWithAge),快速创建一个已经autorelease过的对象;

。创建对象时不要直接用类名,一般用self;

11、ARC的使用(编译器特性):编译器编译代码时若发现alloc则自动生成release;

1> ARC判断准则:只要没有强指针指向对象,就会释放对象;

2> 指针分2种:

① 强指针(__strong,可省略):默认情况下,所有的对象都为强指针;

② 弱指针(__weak):

3> 以前的retain改为strong,其它什么都不变;

4> ARC特点:

① 不允许调用release、retain、retainbCount;

② 允许重写dealloc、但不允许调用[super delloc];

③ @property的参数:

strong:成员变量为强指针,相当于原来的retain(适用于OC对象类型);

weak:成员变量为弱指针,相当于原来的assign(适用于OC对象类型);

assign:适用于非OC对象类型;

5> Xcode的ARC转换功能:

① 自己项目:Edit--Refactor--Convert to OC ARC;

② 引入第三方不是arc的框架:项目右击--Build Phases--选中.m文件--编写:【-fno-objc-arc】;

③ 将项目转为非arc的框架:项目右击--Build Phases--选中.m文件--编写:【-f-objc-arc】;

④ 查看自己项目是否为arc项目:项目右击--Build Settings--搜索auto--Apple LLVM中是否为Yes;

6> ARC循环引用:

① (ARC类型)一端用strong,一端用weak;

② (非ARC类型)一端用retain,一端用assign;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: