关闭

retain的循环引用注意以及@class的使用

标签: retainassign循环引用deallocios
1534人阅读 评论(0) 收藏 举报
分类:

对于retain有一种是循环引用,所谓的循环引用就是两个对象中,互相包含对方,当你在调用我的时候retain一次,而我也调用你的时候也retain一次,导致谁也不能被回收。解决方式就是两对象中的实例变量(oc对象类型)在写@property参数时:

一个写为@propertynonatomic,retainPerson *Person

一个写为@property nonatomic,assignCar *Car

 

下面找个写代码来说明实质性的问题:

有两个类PersonCard,一个人拥有一辆车,一辆车对应一个人。所以代码如下:

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既可。


0
1

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:36312次
    • 积分:852
    • 等级:
    • 排名:千里之外
    • 原创:51篇
    • 转载:0篇
    • 译文:1篇
    • 评论:10条
    最新评论