在之前的一片文章中,我们介绍了数组操作对象的时候引用问题以及自动释放池的概念:

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学习篇之---循环引用问题的更多相关文章

  1. OC学习篇之---总结和学习目录

    今天终于把OC的基础知识学习完了,但是这些知识只是最基础的,还有很多高级知识,这个可能需要后面慢慢的去学习才能体会到.下面就是这次学习OC的目录教程,如果大家发现有什么不正确的地方,请指正,小弟是新生 ...

  2. OC学习篇之---单例模式

    在之前的一片文章中介绍了对象的拷贝相关知识:http://blog.csdn.net/jiangwei0910410003/article/details/41926531,今天我们来看一下OC中的单 ...

  3. (转载)OC学习篇之---概述

    前言 终于开启了OC的学习篇了,之前由于工作上的事,学习就一直搁浅了,不过最近由于各种原因,感觉必须要开启iOS的开发旅程了,不然就老了.因为之前一直是做Android的,所以学习iOS来就没那么费劲 ...

  4. spring源码学习(三)--spring循环引用源码学习

    在spring中,是支持单实例bean的循环引用(循环依赖)的,循环依赖,简单而言,就是A类中注入了B类,B类中注入了A类,首先贴出我的代码示例 @Component public class Add ...

  5. OC学习篇之---对象的拷贝

    在前一篇文章中我们说到了如何解决对象的循环引用问题:http://blog.csdn.net/jiangwei0910410003/article/details/41926369,这一篇文章我们就来 ...

  6. OC学习篇之---数组对象的引用计数问题和自动释放池的概念

    之前一片文章中我们介绍了OC中的两个关键字@property和@synthesize的使用的使用: http://blog.csdn.net/jiangwei0910410003/article/de ...

  7. (转载)OC学习篇之---Foundation框架中的NSDirctionary类以及NSMutableDirctionary类

    昨天学习了Foundation框架中NSArray类和NSMutableArray类,今天来看一下Foundation框架中的NSDirctionary类,NSMutableDirctionary类, ...

  8. (转载)OC学习篇之---Foundation框架中的NSString对象和NSMutableString对象

    在之前的一篇文章中我们说到了Foundation框架中的NSObject对象,那么今天在在来继续看一下Foundation框架中的常用对象:NSString和NSMutableString. 在OC中 ...

  9. (转载)OC学习篇之---Foundation框架中的NSObject对象

    前一篇文章讲到了OC中的代理模式,而且前几篇文章就介绍了OC中的类相关知识,从这篇文章开始我们开始介绍Foundation框架. OC中的Foundation框架是系统提供了,他就相当于是系统的一套a ...

随机推荐

  1. MySQL/RDS数据如何同步到MaxCompute之实践讲解

    摘要:大数据计算服务(MaxCompute,原名ODPS)是阿里云提供的一种快速.完全托管的EB级数据仓库解决方案.本文章中阿里云MaxCompute公有云技术支持人员刘力夺通过一个实验向大家介绍了阿 ...

  2. Codeforces 831C--Jury Marks (思维)

    题目链接:http://codeforces.com/problemset/problem/831/C 题意:有一位参赛选手,我们不知道他初始或最后的成绩,但是知道k次评审所加(减)的分数,以及n个在 ...

  3. C# 实现软件注册功能

    相信很多初学编程的人都会对这个注册功能很感兴趣,我也不例外,刚学asp.net时,竞找不到这方面的实例,结果自己参考微软的一些文档自己做了一个,其实我做的这个注册功能很简单,读取计算机的CPU序列号, ...

  4. BZOJ 5296: [Cqoi2018]破解D-H协议(BSGS)

    传送门 解题思路 \(BSGS\)裸题??要求的是\(g^a =A (mod\) \(p)\),设\(m\)为\(\sqrt p\),那么可以设\(a=i*m-j\),式子变成 \[ g^{i*m-j ...

  5. LOJ 3058 「HNOI2019」白兔之舞——单位根反演+MTT

    题目:https://loj.ac/problem/3058 先考虑 n=1 怎么做.令 a 表示输入的 w[1][1] . \( ans_t = \sum\limits_{i=0}^{L}C_{L} ...

  6. 牛客假日团队赛9 A 乘积最大 (简单DP)

    题目:https://ac.nowcoder.com/acm/contest/1071/A 题意:给你一个串,然后给你m个乘号,用m个乘号分割开这个串,然后求分割可以求出的最大值 思路:首先范围很小 ...

  7. win7NVIDIA显卡驱动升级时卡住

    可以先装上.NET framework,再更新就不会卡了

  8. SQL语言分类DDL、DML、DQL、TCL、DCL

    关系型数据库的SQL语句都可以分为4大类: 1. DDL(数据定义语言)     DDL 主要是指如下的四种SQL 语句,以 CREATE.DROP.ALRET开头和 TRUNCATE TABLE 语 ...

  9. HTML版简历

    页面预览 在线演示

  10. QTP 保留对象

    1. 常用保留对象(Utility Objects) 保留对象:所谓QTP保留对象就是QTP本身预留的一些可用对象. 通俗些讲就是,当打开QTP时它就已经把这些对象给实例化了,直到关闭QTP后,这些保 ...