Objective-c 循环引用
2015-09-05 20:32
555 查看
Objective-c 循环引用
OC内存管理中有一种特殊的对象管理,那就是循环引用。循环引用即是类A中有类B作为成员变量,同时类B中又同时有类A作为成员变量。这种情况下,引用计数器需要特殊的处理。下面分别介绍非ARC情况下的循环引用和ARC情况下的循环引用。
一、非ARC情况下的循环引用,Person类中包含Card类,Card类中包含Person类。
1、Person类中对card类进行retain ,所以需要进行release。
二、ARC情况下的循环引用
为了便于对比,还是使用 Person类和Card类的循环引用
1、Person类中对card类指针定义为strong指针
2、Card类中,为了保持指向Person对象的strong指针数量不变,所以使用weak
3、main函数中,写清楚了 每一个对象的strong指针数量的变化:
小结:在ARC中,两个类之间进行循环引用,应该一端 使用strong,另一端使用 weak。因为,在ARC条件下,系统判断对象是否销毁的标准是:指向对象空间的strong指针的总数是否为0 ,如果归零,代表对象已经销毁。 对象是否销毁与 weak指针没有任何关系。如果,weak指针指向的对象空间销毁了,系统会自动是 weak指针归nil 。
说到底,ARC情况下的 对象拥有的strong指针的个数 等价于 非ARC情况下的 retainCount。只要记住这一条,两者就很容易辨别了。
下面附上内存图,便于理解,实线代表强指针,虚线代表弱指针。
OC内存管理中有一种特殊的对象管理,那就是循环引用。循环引用即是类A中有类B作为成员变量,同时类B中又同时有类A作为成员变量。这种情况下,引用计数器需要特殊的处理。下面分别介绍非ARC情况下的循环引用和ARC情况下的循环引用。
一、非ARC情况下的循环引用,Person类中包含Card类,Card类中包含Person类。
1、Person类中对card类进行retain ,所以需要进行release。
#import <Foundation/Foundation.h> @class Card;//因为需要用到,所以声明 @interface Person : NSObject //属性是一个Card类, 对象被引用,所以用retain @property (nonatomic,retain)Card *card; @end
#import "Person.h" #import "Card.h"//.m中需要知道Card类的具体实现 @implementation Person - (void)dealloc { NSLog(@"Person被销毁了"); [_card release];//有retain,所以需要release [super dealloc]; } @end2、Card类中,为了Person对象的retainCount 不改变,所以使用assign 进行直接赋值
#import <Foundation/Foundation.h> @class Person; @interface Card : NSObject // 使用assign,是Person对象的retainCount不 +1 @property (nonatomic,assign)Person *person; @end
#import "Card.h" @implementation Card - (void)dealloc { NSLog(@"Car被销毁了"); //不对_person进行release,因为使用的是assign [super dealloc]; } @end3、main函数中,写清楚了 每一个对象的retainCount的变化:
#import <Foundation/Foundation.h> #import "Person.h" #import "Card.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [[Person alloc] init];//p的retainCount 1 Card *c = [[Card alloc] init];//c的retainCount 1 p.card = c;//c的retainCount 1+1=2 c.person = p;//p的retainCount 1 不变 [c release];//c的retainCount 2-1=1 [p release];//p和c的retainCount 都是 0 } return 0; }小结:在非ARC中,两个类之间进行循环引用,应该一端 使用retain,另一端使用 assign。因为,计数器只要实现一端引用是+1,另一端中不需要+1 ,所以使用assign 。
二、ARC情况下的循环引用
为了便于对比,还是使用 Person类和Card类的循环引用
1、Person类中对card类指针定义为strong指针
#import <Foundation/Foundation.h> @class Card; @interface Person : NSObject @property (nonatomic,strong)Card *card; @end
#import "Person.h" #import "Card.h" @implementation Person - (void)dealloc { NSLog(@"Person被销毁了"); //[_card release];不需要手动释放了 //[super dealloc];//ARC下不能调用[super dealloc] } @end
2、Card类中,为了保持指向Person对象的strong指针数量不变,所以使用weak
#import <Foundation/Foundation.h> @class Person; @interface Card : NSObject @property (nonatomic,weak)Person *person; @end
#import "Card.h" @implementation Card - (void)dealloc { NSLog(@"Car被销毁了"); //ARC情况下可以重写dealloc,但是不能调用[super dealloc]; } @end
3、main函数中,写清楚了 每一个对象的strong指针数量的变化:
#import <Foundation/Foundation.h> #import "Person.h" #import "Card.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [[Person alloc] init];//p 是1条强指针,指向Person 空间 Card *c = [[Card alloc] init];//p 是1条强指针,指向Card空间 p.card = c;//p.card 也是一条强指针指向Card空间,2条 c.person = p;//c.person 是一条weak指针, 所以Person空间强指针还是 1 } //自动释放池,结束会向p和c 各自发送一条 release消息 // 最后相当于手动管理中对象的retainCount都会变为0; return 0; }
小结:在ARC中,两个类之间进行循环引用,应该一端 使用strong,另一端使用 weak。因为,在ARC条件下,系统判断对象是否销毁的标准是:指向对象空间的strong指针的总数是否为0 ,如果归零,代表对象已经销毁。 对象是否销毁与 weak指针没有任何关系。如果,weak指针指向的对象空间销毁了,系统会自动是 weak指针归nil 。
说到底,ARC情况下的 对象拥有的strong指针的个数 等价于 非ARC情况下的 retainCount。只要记住这一条,两者就很容易辨别了。
下面附上内存图,便于理解,实线代表强指针,虚线代表弱指针。
相关文章推荐
- Flex中用RemoteObject与java后台通信
- Hibernate 异常:object references an unsaved transient instance - save the transient instance before fl
- object references an unsaved transient instance - save the transient instance before flushing
- 条款12:复制对象时勿忘其每一个成分(Copy all parts of an object)
- IOS学习笔记3—Objective C—简单的内存管理
- IOS学习笔记2—Objective C—类、属性、方法
- Object-C中获取当前触摸点的坐标位置
- 黑马程序员——Objective-C之对象特性
- org.hibernate.PersistentObjectException: detached entity passed to persist异常
- Java学习笔记--HashMap中使用object做key的问题【转】
- EF ObjectStateManager无法跟踪具有相同键的多个对象
- 2.1.1 Minimal Shader (about shaders, materials, and game objects) 极简的着色器(关于着色器,材质和游戏物体)
- ActionScript 3.0 学习(八) AS3 简单的缓存功能实现之SharedObject类
- Objective-c 单例设计模式
- Objective-C( Foundation框架 一 常见的结构体)
- Effective Objective-C 2.0 第4条:多用类型常量,少用#define预处理指令
- Objective-C常用类的常用方法
- Objective-C类,NSUrl介绍和使用
- Objective-C Programming (2nd Edition)
- Objective-C类,NSBundle介绍和使用