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 ...
随机推荐
- sublime常用基础插件合集
插件介绍 Package Control 功能:安装包管理简介:sublime插件控制台,提供添加.删除.禁用.查找插件等功能使用方法:快捷键 Ctrl+Shift+P,输入 install 选中In ...
- 多列布局(column)
容器的属性 column-width: auto | < length > .给列定义一个最小宽度(min-width). auto: 列宽由其他元素决定. length: 显式设置最小宽 ...
- (转)PAL制式和NTSC制式的区别
转:https://www.cnblogs.com/nx520zj/articles/6061777.html 常见的电视信号制式是PAL和NTSC,另外还有SECAM等. NTSC即正交平衡调幅制. ...
- C# Self Injector into non managed process
Hey all, I'm gonna explain you how make a self injecting program in C#.I hope you guys thinks its us ...
- mysql8.0 新特性,对json类型的常用操作
mysql8 新特性-json数据类型操作 -- 根据key(可多个)获取value SELECT JSON_EXTRACT('{"id": 14, "name" ...
- 使用Python的PIL模块来进行图片对比
使用Python的PIL模块来进行图片对比 在使用google或者baidu搜图的时候会发现有一个图片颜色选项,感觉非常有意思,有人可能会想这肯定是人为的去划分的,呵呵,有这种可能,但是估计人会累死, ...
- cabal替代脚本
由于网络原因,直接使用cabal update不成功,只能自己写脚本直接从网上拖包下来,自己安装. 但是这样做的缺点是需要手动处理dependency,当然,也可以把脚本写的复杂些,自动来处理depe ...
- Python3函数中特殊形参的使用:*、*args、**kwargs
Python3函数中特殊形参的使用:*.*args.**kwargs ==用法1:不定长参数== 当函数需要的参数数量不确定的时候,可以使用*args 和 **kwargs , 所有的位置参数保存在* ...
- 偏向锁,偏向线程id ,自旋锁
理解锁的基础知识 如果想要透彻的理解Java锁的来龙去脉,需要先了解以下基础知识. 基础知识之一:锁的类型 锁从宏观上分类,分为悲观锁与乐观锁. 乐观锁 乐观锁是一种乐观思想,即认为读多写少,遇到并发 ...
- 服务器oracle数据库定时备份
首先要先建立一个.bat的文件 然后执行这个bat文件 测试是否能得到这个收据库的打包文件. bat文件内容: @echo off@color bdel /f /s /q D:\oracle\bac ...