OC学习篇之---循环引用问题
在之前的一片文章中,我们介绍了数组操作对象的时候引用问题以及自动释放池的概念:
http://blog.csdn.net/jiangwei0910410003/article/details/41926183
今天我们继续来看一下引用计数中一个痛疼的问题:循环引用
关于循环引用的问题,这里就不做太多解释了,就是多个对象之间相互引用,形成环状。
来看一个具体的例子:
Dog类和Person类之间相互引用
Dog.h
//
// Dog.h
// 29_CyclePointer
//
// Created by jiangwei on 14-10-13.
// Copyright (c) 2014年 jiangwei. All rights reserved.
// #import <Foundation/Foundation.h> #import "Person.h" @interface Dog : NSObject //这里不用retain,如果使用retain的话,会形成循环引用
@property(nonatomic,assign,readwrite) Person *person; - (void)dealloc; @end
Dog.m
//
// Dog.m
// 29_CyclePointer
//
// Created by jiangwei on 14-10-13.
// Copyright (c) 2014年 jiangwei. All rights reserved.
// #import "Dog.h" @implementation Dog - (void)dealloc{
//[_person release];
NSLog(@"dog dealloc");
[super dealloc];
} @end
Dog类中有一个Person类型的属性
Person.h
//
// Person.h
// 29_CyclePointer
//
// Created by jiangwei on 14-10-13.
// Copyright (c) 2014年 jiangwei. All rights reserved.
// #import <Foundation/Foundation.h> @class Dog; @interface Person : NSObject @property(nonatomic,retain,readwrite) Dog *dog; - (void)dealloc; @end
Person.m
//
// Person.m
// 29_CyclePointer
//
// Created by jiangwei on 14-10-13.
// Copyright (c) 2014年 jiangwei. All rights reserved.
// #import "Person.h" #import "Dog.h" @implementation Person - (void)dealloc{
[_dog release];
NSLog(@"Person dealloc");
[super dealloc];
} @end
Person类中有Dog类型的属性
看一下测试代码
main.m
//
// main.m
// 29_CyclePointer
//
// Created by jiangwei on 14-10-13.
// Copyright (c) 2014年 jiangwei. All rights reserved.
// #import <Foundation/Foundation.h> #import "Dog.h"
#import "Person.h" //循环引用
//是一个很麻烦的一件事,完全靠经验
int main(int argc, const char * argv[]) { Person *p = [[Person alloc] init];
Dog *dog = [[Dog alloc] init]; [p setDog:dog];//dog计数:2 [dog setPerson:p];//person计数:2 [p release]; //person计数:1
[dog release];//dog计数:1 //没有释放的原因是dealloc方法中没有被执行,里面的释放代码也就没执行了,dog和person各自在等待,形成环状了
//解决版本就是切断他们之间的联系
//@property中不使用retain,使用assgin NSLog(@"is over"); return 0;
}
我们分别定义了一个Person对象和Dog对象,然后相互引用了,但是当我们调用他们的release方法的时候,这两个对象并没有被释放
原因很简单:
person和dog的相互引用了,当执行release方法的时候引用计数都还是1,所以就不会调用dealloc方法了
dealloc方法中没有被执行,里面的释放代码也就没执行了,dog和person各自在等待,形成环状了
解决的办法是:
切断他们之间的联系
在一方中定义属性的时候,@property中不使用retain,使用assgin
同时在dealloc方法中不再调用release方法了
上面的例子中,我们可以看到Dog类中就是使用assgin
总结
循环引用是对象销毁的时候遇到的最大的一个问题,在java中,垃圾回收器也会遇到这样的问题,所以就不采用引用计数法去管理对象了,而是另外的一种方式去管理,可以参考:http://blog.csdn.net/jiangwei0910410003/article/details/40709457
OC学习篇之---循环引用问题的更多相关文章
- OC学习篇之---总结和学习目录
今天终于把OC的基础知识学习完了,但是这些知识只是最基础的,还有很多高级知识,这个可能需要后面慢慢的去学习才能体会到.下面就是这次学习OC的目录教程,如果大家发现有什么不正确的地方,请指正,小弟是新生 ...
- OC学习篇之---单例模式
在之前的一片文章中介绍了对象的拷贝相关知识:http://blog.csdn.net/jiangwei0910410003/article/details/41926531,今天我们来看一下OC中的单 ...
- (转载)OC学习篇之---概述
前言 终于开启了OC的学习篇了,之前由于工作上的事,学习就一直搁浅了,不过最近由于各种原因,感觉必须要开启iOS的开发旅程了,不然就老了.因为之前一直是做Android的,所以学习iOS来就没那么费劲 ...
- spring源码学习(三)--spring循环引用源码学习
在spring中,是支持单实例bean的循环引用(循环依赖)的,循环依赖,简单而言,就是A类中注入了B类,B类中注入了A类,首先贴出我的代码示例 @Component public class Add ...
- OC学习篇之---对象的拷贝
在前一篇文章中我们说到了如何解决对象的循环引用问题:http://blog.csdn.net/jiangwei0910410003/article/details/41926369,这一篇文章我们就来 ...
- OC学习篇之---数组对象的引用计数问题和自动释放池的概念
之前一片文章中我们介绍了OC中的两个关键字@property和@synthesize的使用的使用: http://blog.csdn.net/jiangwei0910410003/article/de ...
- (转载)OC学习篇之---Foundation框架中的NSDirctionary类以及NSMutableDirctionary类
昨天学习了Foundation框架中NSArray类和NSMutableArray类,今天来看一下Foundation框架中的NSDirctionary类,NSMutableDirctionary类, ...
- (转载)OC学习篇之---Foundation框架中的NSString对象和NSMutableString对象
在之前的一篇文章中我们说到了Foundation框架中的NSObject对象,那么今天在在来继续看一下Foundation框架中的常用对象:NSString和NSMutableString. 在OC中 ...
- (转载)OC学习篇之---Foundation框架中的NSObject对象
前一篇文章讲到了OC中的代理模式,而且前几篇文章就介绍了OC中的类相关知识,从这篇文章开始我们开始介绍Foundation框架. OC中的Foundation框架是系统提供了,他就相当于是系统的一套a ...
随机推荐
- 【bzoj1185】[HNOI2007]最小矩形覆盖 (旋转卡壳)
给你一些点,让你用最小的矩形覆盖这些点 首先有一个结论,矩形的一条边一定在凸包上!!! 枚举凸包上的边 用旋转卡壳在凸包上找矩形另外三点... 注意精度问题 #include<cstdio> ...
- 2017 ACM-ICPC乌鲁木齐网络赛 B. Out-out-control cars(计算几何 直线相交)
题目描述 Two out-of-control cars crashed within about a half-hour Wednesday afternoon on Deer Park Avenu ...
- Vue使用的扩展
1.Bus(总线)实现非父子组件通信 Vue2.0提供了Vuex进行非父子组件之间的通信,但在简单的场景下,可以使用一个空的Vue实例作为中央事件总线. 实现代码示例: <div id=&quo ...
- python中的生成器和迭代器
前言: 我们来了解一下什么是python中生成器.了解一下python生成器是什么,以及生成器在python编程之中能起到什么样的作用. 定义: 生成器和迭代器 通过列表生成式,我们可以直接创建一个列 ...
- JAVA 大数开方模板
JAVA 大数开方模板 import java.math.BigInteger; import java.math.*; import java.math.BigInteger; import jav ...
- 老牌激活工具 — Microsoft Toolkit 2.5.1正式版【转】
老牌激活工具 — Microsoft Toolkit 2.5.1正式版 Microsoft Toolkit 2.5.1是一个一键激活MS Office 及 win系统的工具.原理就是利用KMS来激活 ...
- 使用SSH方式实现Git远程连接GitHub/gitlab
参照: https://blog.csdn.net/wuli_smbug/article/details/81480162
- datastudion 资源导入python包,编写模块
学习文档,不懂再问. https://help.aliyun.com/document_detail/74423.html?spm=a2c4g.11186623.6.688.72635debHqgkV ...
- flysql 里两种传参的方式
传参的方式,两个标清楚: for lists_bx_goods in out_list: sql = XDO().get_update_sql('init_goods_test', { "一 ...
- PHP解码unicode编码的中文字符
问题背景:晚上在抓取某网站数据,结果在数据包中发现了这么一串编码的数据:"......\u65b0\u6d6a\u5fae\u535a......www.jinyuanbao.cn" ...