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

原创 2015年07月07日 23:54:27

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


循环引用之【#import】【@class】和循环【retain】之【assign】

一、循环引用 // // Person.h // OCStudy // // Created by LiuMingchuan on 15/9/26. // Copyright © 2015年 ...

黑马程序员----Objective-C学习笔记之@class与循环retain问题

------Java培训、Android培训、iOS培训、.Net培训-------- 一、@class的使用方法 1、使用 【@import】会把引用的头文件整个拷贝到@import的使用...

#include、#import与@class的使用与头文件循环引用问题

#include #include :通常是对系统库文件的引用,编译器会去系统文件目录下查找。 那么这就会导致了头文件循环引用的问题了,通常都是出现虽然你导入了该头文件,但在使用时比如使用`@prop...
  • CNLF14
  • CNLF14
  • 2015年08月19日 10:47
  • 2582

IOS中的block的retain循环

来源:http://www.cnblogs.com/tangbinblog/archive/2012/12/31/2840690.html IOS中的block和retain cycle (经典) ...

黑马程序员——OC---MRC里的循环retain问题

黑马程序员——OC---几个循环引用问题的回顾 ------- android培训、java培训、期待与您交流! ----------...

黑马程序员——IOS基础——OC内存管理循环retain和autorelease

涉及到循环引用:身份证Card和人Person
  • kldxcr
  • kldxcr
  • 2014年04月04日 18:26
  • 673

OC学习笔记07--OC中内存管理与循环retain问题

#import //告诉编译器ClassB是一个类 @class ClassB; //ClassA @interface ClassA : NSObject { ClassB *_b; }...

循环retain导致内存泄露

问题描述Dog.h#import @class Person; @interface Dog : NSObject @property (nonatomic,retain) Person *owne...

【OC笔记】MRC中多对象内存管理以及循环retain

一、多对象内存管理要点:对象中类类型的属性以及NSSting类型属性的内存管理问题,以及多对象内存管理注意事项。代码示例:Person类的声明和实现@interface Person : NSObje...

黑马程序员——OC——循环retain和autorelease

循环retain
  • DLonion
  • DLonion
  • 2014年06月29日 15:44
  • 225
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:retain的循环引用注意以及@class的使用
举报原因:
原因补充:

(最多只允许输入30个字)