1.方法的基本使用
OC对象内部都有一个自己的引用计时器,用来表示“对象倍引用的次数”每个引用计时器占用四个字节的存储空间即2^4。对象被创建的时候引用计时器默认值为1;当一个对象计数器值为0的时候,对象占用的内存就会倍系统回收;在整个程序已经退出的时候该程序创建的所有的对象都将被回收。
引用计时器的操作:
当我们给对象发送一条retain消息,可以使引用计时器值+1,retain方法返回对象本身。
给对象发送一条release消息,可以使引用计时器值-1.
可以给对象发送retainCount消息获得当前的引用计数器值;
dealloc:当一个对象要被回收的时候,就会调用。
被释放的对象(所用内存已经被回收):僵尸对象
指向僵尸对象的指针:野指针 给野指针发送消息会报错。
没有指向任何东西的指针称为空指针(存储的东西是nil、null、0),给空指针发送消息不会报错。
例如:
Person *p = [[Person alloc]init];
[p release];
p.name = @"Jake";
一般在对象被回收之后要将指针清空:
[p release];
p = nil;
无论以后在怎么操作p都不会报错 OC中不存在空指针错误,给空指针发送消息,不会报错。为了在以后的开发中不产生错误应该开启僵尸对象检测:点击项目名弹出下拉菜单,点击Eidt Scheme ,选定Diagnostics,然后选定僵尸对象检测。
再运行时,空指针就会报错。 messagessent to deallocated instance (地址):
2.多个对象之间的内存管理原则
1.谁想用(占用)某个对象,就用该让对象的计数器+1(让对象做一次retain操作)
2.不想使用(占用)某个对象,就应该让对象的计数器-1(让对象做一次release)
3.谁retain ,就让谁release
4.谁alloc,就让谁release
3.setter的内存管理
内存管理规范:
1. 只要调用了alloc,必须有realease(autorelease)
2. 如果对象不是由alloc创建的就不需要release;
3. set方法的代码规范
1) 基本数据类型:直接赋值 例如;
- (void)setAge:(int)age
{
_age = age;
}
2) OC对象类型:
- (void)setCar:(Car *)car
{
if(car != _car)
{
[_car release];
_car = [car retain];
}
}
4. property参数的设置(非ARC)
1) setter内存相关的参数:
retain:release旧址,retain新值(适用于OC对象类型)
assign:直接赋值,适用于非OC对象
copy:release旧址,copy新值
2) 是否要生成setter
readwrite:同时生成setter和getter声明和实现
readonly:只会生成getter的声明和实现
3) 多线程管理方面
nonatomic:性能高(一般用这个)
atomic :性能低(默认)
4) setter和getter的名称
例如:(getter = abc)则调用的时候使用 [p abc];
(setter = abc;)注意后面的冒号
即使在修改名字之后也可以原来的方法修改 ,这种方法一般用用在bool类型中:
@property(getter = isRich) bool rich;
调用的时候
bool isRich = p.isRich
在以后的@property中,如果对象方法的话加参数retain,即可在生成的setter中加入retain方法。但是在delloc还是要调用retain。将对象多拥有的对象释放(如:人拥有的一本书)。
5) 在两个对象相互依赖关系时,比如:人拥有一本书,书被人占用
为防止互相引用,在.h中@class 来声明类,在.m文件中再import对方的.h文件。
@class的作用:仅仅告诉编译器,某个名称是一个类,一段在@property中用retain ,另一端中使用assign。
5. 自定义构造方法
在初始化的时候给定一个初始值,构造方法都是对象方法,一般返回值都是id类型,方法名以initWith开头。代码示例:
- (id)initWithAge:(int)age
{
if( self = [super init] ) // 先地调用一次super的init 成功以后在进行操作
{
_age = 10;
}
return self; // 最后返回
}
6. autorelease
为防止对象调用release的位置不合适,在创建对象的时候加入autorelease参数,他会返回对象本身,在对象被创建时放到自动释放池中,在自动释放池被销毁的时候会对池子里所有的对象做一次release操作。在ios程序运行中,会创建无数个池子。这些池子都是以栈结构存在的(先进后出)。
系统自带的方法中,如果不包含alloc、new、copy 那么这些方法返回的对象都是已经autorelease过得:[ NSString stringWithFormat…]
7. ARC的使用
在使用了ARC的程序中,不需要开发者再管理内存,不允许再调用release、retain、、retainCount,允许重写dealloc,但是不允许调用[super dealloc],当没有强指针指向对象的时候,就会释放对象。在默认情况下,所有的指针都是强指针 __strong,弱指针用 __weak修饰(前面是两个下划线)。
在@property中参数
strong:成员变量是强指针,相当于原来的retain(适用于OC对象类型)
weak:成员变量是弱指针,相当于原来的assign(适用于OC对象类型)
assign:适用于非OC对象
当两端循环引用的时候,一段用strong 另一端使用weak。