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


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

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

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

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

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

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

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

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

涉及到循环引用:身份证Card和人Person

IOS中的block的retain循环

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

循环retain导致内存泄露

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

喜欢用Block的值得注意-Block的Retain Cycle的解决方法

本文不讲block如何声明及使用,只讲block在使用过程中暂时遇到及带来的隐性危险。 主要基于两点进行演示: 1.block 的循环引用(retain cycle) 2.去除blo...

Implement CircularArray class 实现循环数组

题目内容 Circular Array: Implement a circular array class that supports an array-like data structure wh...

Java基础---基础加强---增强for循环、自动拆装箱及享元、枚举的作用、实现带有构造方法、透彻分析反射的基础_Class类、成员变量的反射、数组参数的成员方法进行反射、数组的反射应用

在perference 加content Assist 可以设置快捷键 透视图与视图 透视图:Debug和java主窗口 视图:每一个小窗口就是视图 高版本的java可运行低版本的java版本 常见...

关于iOS的强引用,弱引用及strong,retain,copy,weak,assignd的关系

强引用和弱引用: 我们已经知道OC中的内存管理是通过“引用计数器”来实现的。一个对象的生命周期取决于它是否还被其他对象引用(是否retainCount=0)。但在有些情况下,我们并不希望对象的销...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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