标签:retain assign 循环引用 dealloc ios
对于retain有一种是循环引用,所谓的循环引用就是两个对象中,互相包含对方,当你在调用我的时候retain一次,而我也调用你的时候也retain一次,导致谁也不能被回收。解决方式就是两对象中的实例变量(oc对象类型)在写@property参数时:
一个写为@property(nonatomic,retain)Person *Person;
一个写为@property (nonatomic,assign)Car *Car;
下面找个写代码来说明实质性的问题:
有两个类Person和Card,一个人拥有一辆车,一辆车对应一个人。所以代码如下:
1)Person.h #import <Foundation/Foundation.h> @class Car; @interface Person : NSObject @property (nonatomic,retain) Car *car; @end 2)person.m #import "Person.h" #import "Car.h" @implementation Person -(void)dealloc { [_car release]; NSLog(@"Person对象被回收"); [super dealloc]; } @end 3)Car.h #import <Foundation/Foundation.h> @class Person; @interface Car: NSObject @property (nonatomic,assign)Person *person; @end 4)Car.m #import "Car.h" @implementation Car -(void)dealloc{ NSLog(@"car对象被回收"); [super dealloc]; } @end 5)main. #import <Foundation/Foundation.h> #import "Car.h" #import "Person.h" int main(int argc, const char * argv[]) { //p-1(计数器是1) Person *p = [[Person alloc]init]; //c-1 Car *c = [[Car alloc] init]; //c-2 p.car = c ; //p-1 c.person = p; //c-1 [c release]; //p-0,c-0 [p release] return 0; }
图分析如下:
如果两个类中都写为@property(nonatomic,retain)Person *p;
@property(nonatomic,retain)Car *c;
程序执行过程中 内存如图所示:
程序结束后,对象并没有被回收,所以造成内存泄露。
如果Car.h中把@property参数中的retain改为assign,则意味着只是赋值,_person不用执行retain操作,所以当执行到[p release]时 p的计数器从1-0,所以对象p回收,进入到p的dealloc方法中,执行[_car release],c的计数器从1-0;回收对象c,然后回收对象p;
所以循环引用解决方式:
一端用retain
一端用assign
值得注意的是: @class 类A 一般用于类B.h 文件 表示在类B中声明有一个类A,当然仅仅是声明,并不是把类A的属性和方法拷贝过来。而#import 则是把属性和方法全拷贝过来,如果很多文件都#imoport这个文件的话,当这个头文件被修改时,则那些很多的文件都需要重新编译,但是@class则不需要,它只需要在用到时,在类B.m文件中#import既可。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:retain assign 循环引用 dealloc ios
原文地址:http://blog.csdn.net/miaopf123/article/details/46797115