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


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

本文主要说明了retain循环的循环引用及解决方法。
  • miaopf123
  • miaopf123
  • 2015年07月07日 23:54
  • 1668

retain和release倒底怎么玩?

http://blog.csdn.net/musicvs/article/details/8689345 1. 为什么会有retain? C++和Java不一样,Java有一套很方便的...
  • taotaoah
  • taotaoah
  • 2015年05月28日 21:37
  • 199

探讨OC的内存管理 以及防止循环引用retain cycle 代理为什么用weak block为什么用copy

首先声明OC的内存管理机制:引用计数。当一个对象的引用计数为0时,这个对象就会被释放。铭记以上两点,我们开始来探讨。 换句话说,如果一个对象,没有强指针指向,就会被释放。举个很形象的例子,假如每一个对...
  • qinqi376990311
  • qinqi376990311
  • 2016年10月26日 15:17
  • 674

和block循环引用说再见

to be block? or to be delegate? 这是一个钻石恒久远的问题。个人在编码中暂时没有发现两者不能通用的地方,习惯上更偏向于block,没有什么很深刻的原因,只是认为block...
  • Lotheve
  • Lotheve
  • 2016年07月22日 10:29
  • 2598

objective-c循环retain和@class

一、关于@class 1.使用场景 对于循环依赖关系来说,A类引用B类,同时B类也引用A类,这种代码编译会报错。当使用@class在两个类相互声明,就不会报错了。 2.用法概括 ...
  • aa641462576
  • aa641462576
  • 2014年10月31日 20:38
  • 297

黑马程序员---内存管理之循环retain和@class

———Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ———
  • zhangyun2013
  • zhangyun2013
  • 2014年10月19日 22:40
  • 298

iOS开发——Block引起循环引用的解决方案

内存问题始终是软件开发中的头等大事,iOS开发中也不例外,在面试中也是必问的问题。今天我们主要来讲讲Block中涉及的循环引用问题。当我们自己一开始写代码的时候,可能会大量在block中使用self,...
  • CHENYUFENG1991
  • CHENYUFENG1991
  • 2016年03月18日 01:04
  • 7923

iOS @property retain关键字的使用

assign: 简单赋值,不更改索引计数 copy: 建立一个索引计数为1的对象,然后释放旧对象 retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 Copy其实是建...
  • u012165769
  • u012165769
  • 2016年03月01日 22:46
  • 462

retain和release倒底怎么玩?

http://blog.csdn.net/musicvs/article/details/8689345 retain和release倒底怎么玩?   呼呼,好久没有...
  • taotaoah
  • taotaoah
  • 2015年04月28日 08:15
  • 236

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

一、多对象内存管理要点:对象中类类型的属性以及NSSting类型属性的内存管理问题,以及多对象内存管理注意事项。代码示例:Person类的声明和实现@interface Person : NSObje...
  • WackoSix
  • WackoSix
  • 2015年08月17日 08:09
  • 379
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:retain的循环引用注意以及@class的使用
举报原因:
原因补充:

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