ARC规则及使⽤

所有权修饰

__strong
__weak
__ unsafe_unretained
__ autoreleasing


__strong 修饰符是 id 类型和对象类型默认的所有权修饰符。

idobj= [[NSObjectalloc]init];(默认)

id__strong obj= [[NSObjectalloc]init];

id和对象类型没有明确制定所有权修饰符时,默认为__strong


 //ARC有效

  //自己生成并持有对象 

  id __strong obj =[ [NSObjectalloc]init];

}

//变量obj超出其作用域,强引用失效,自动释放自己吃用的对象。对象的持有者不存在,因此废弃对象

附有__strong修饰符的变量obj在超出其变量作用域时,即在该变量被废弃时,会释放被其赋予的对象。


{//取得非自己生成并持有的对象

  id __strong obj = [NSMutableArrayarray];

//变量obj为强引用,持有自己的对象

}

//因为变量obj超出其作用域,强引用失效,自动释放自己吃用的对象


id__strong obj0 = [[NSObjectalloc]init];//对象A

id__strong obj1 = [[NSObjectalloc]int];//对象B

id__strong obj2 = nil;

obj0= obj1;

/*obj0持有由obj1赋值的对象B的强引用,因为obj0被赋值,所以原先持有的对对象A的强引用失效,对象A的所有者不存在,因此废弃对象A;此时持有对象B的强引用的变量变为obj0obj1*/

obj2= obj0

/*obj2持有由obj0赋值的对象B的强引用,此时持有对象B的强引用的变量为obj0obj1obj2*/

obj1= nil

/*因为nil被赋予了obj1,所有对对象B的强引用失效,此时持有对象B的强引用的变量为,obj0obj2*/

obj0= nil;

obj2= nil;

//对象B的所有者不存在,因此废弃对象B



{

  id __strong test = [[Test alloc]init];

  //test 持有Test对象的强引用

  [test setObject:[[NSObjectalloc]init]];

  //Test对象的obj_成员,持有NSObject对象的强引用

}

/*因为test变量超出其作用域,强引用失效,所以自动释放Test对象;Test对象的所有者不存在,因此废弃该对象;

废弃该对象的同时,Test对象的obj_成员也被废弃,NSObject对象的强引用失效,自动释放NSObject对象;NSObject对象的所有者不存在,因此废弃该对象*/




{

  id test0 = [[Test alloc]init];//对象A

  id test1 = [[Test alloc]init];//对象B

  [test0 setObject:test1];

//Test对象Aobj_成员持有Test对象B的强引用;此时,持有Test对象B的强引用变量为Test对象Aobj_test1

  [test1 setObject:test0];

//Test对象B达到obj_成员持有Test对象A的强引用;此时,持有Test对象A的强引用的变量为Test对象Bobj_test0

}

/*因为test0变量超出其作用域,强引用失效,所以自动释放Test对象Atest1变量也超出其作用域,强引用失效,自动释放Test对象B

此时持有Test对象A的强引用的变量为Test对象Bobj_

持有Test对象B的强引用变量为Test对象Aobj_

内存泄露*/



循环引用容易引起内存泄露——应当废弃的对象在超出其生存期后继续存在。

对象在不被任何持有的状态下应予以废弃,但是,循环引用使得对象不能被再次废弃。

__weak修饰符的变量(即弱引用)不持有对象,所以在超出其变量作用域时,对象即被释放

自身强引用

idtest = [[Test alloc]init];

[testsetObject:test];



{

  //自己生成并持有对象

  id __strong obj0 = [[NSObjectalloc]init];

  //因为obj0变量为强引用,所以自己持有对象

  id __weak obj1 = obj0;

  //obj1变量持有生成对象的弱引用

}

/*因为obj0变量超出其作用域,强引用失效,自动释放自己持有的对象。因为对象的所有者不存在,所以废弃该对象

*/



__weak修饰符,在持有某对象的弱引用时,若该对象被废弃,则此弱引用强自动失效且处于nil被赋值状态(空弱引用)

id__weak obj1 = nil;

{

  //自己生成并持有对象

  id __strong = [[NSObjectalloc]init];  //因为obj0变量为强引用,所以自己持有对象

  obj1 = obj0; //obj1持有对象的弱引用

  NSLog(@A: %@, obj1);//输出obj1变量持有的弱引用的对象

}

/*因为obj0变量超出其作用域,强引用失效,自动释放自己持有的对象;因为对象无持有者,所以废弃该对象

废弃对象的同时,持有该对象的弱引用的obj1变量的弱引用失效,nil赋值给obj1*/
NSLog(@B:%@,obj1); //输出赋值给obj1变量中的nil




使用__weak修饰符可避免循环引用。通过检查附有__weak修饰符变量是否为nil,可以判断被赋值的对象是否已废弃

__weak修饰符只能用于iOS5以上及OS X Lion以上版本的应用程序。在iOS4以及OS X Snow Leopard的应用程序中可使用__unsafe_unretained修饰符代替

 

//ARC无效

NSAutoreleasePool* poo

 =[[NSAutoreleasePoolalloc]init];

//ARC有效

@autoreleasepool{

  id __autoreleaseingobj2;

  obj2 = obj;

}


设置 ARC 时禁止再次键入 retain 或者是 release
须遵循内存管理的方法命名规则

ARC无效时,用于生成/持有的方法必须遵守以下命名规则,allocnewcopymutableCopy上述名称开始的方法在返回对象时,必须返回给调用方所应当持有的对象。ARC有效时需要在添加一条

init  init开始的方法,必须是实例方法,并且必须要返回对象

-(id)initWithObject:(id)obj;



不能显式的调用 dealloc

-(void)dealloc{

/*

  此处运行该对象被废弃时必须实现的代码

*/

  free(buffer_);

  [[NSNotificationCenterdefautlCenter]removeObserver:self];

}

//不能书写[superdealloc];



对象型变量不能作为 C 语言结构体成员

structData{

  NSMutableArray* array;

};

error:ARCforbids Objective-C objsinstructsor unionsNSMutableArray* array;

要把对象型变量加入到结构体成员中,可强制转换为void*或者是附加__unsafe_unretained修饰符

structData{

  NSMutableArray__unsafe_unretained* array;

};



显式转换 id void*( 多用在 Objective-C 对象与 Core Foundation 对象之间的相互转换 )

__bridge_retained转换与retain类似,__bridge_transfer转化与release相似;再给idobj赋值时retain即相当于__strong修饰符的变量.

void* p = (__bridge_retainedvoid *) [[NSObjectalloc]init];

NSLog(@class= %@,[(__bridge id)p class]);

(void)(__bridge_transferid)p;

ARC有效时属性声明的属性与所有权修饰符的对应关系

属性声明

所有权修饰符

assign

__unsafe_unretained修饰符

copy

_strong修饰符(但是赋值的是被复制的对象)

retain

_strong修饰符

strong

__strong修饰符

unsafe_unretained

__unsafe_unretained修饰符

weak

__weak修饰符








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值