iOS复习笔记7:循环引用问题

1 @class

@class ClassName,仅仅告诉编辑器ClassName是一个类

避免循环拷贝

在.h中使用@class声明

在.m文件中import头文件

2 循环引用问题

2.1 定义:

指两个对象互相retain对方,通过release是无法销毁这两个对象

2.2 描述:

比如在main函数中创建了两个类的对象A和B,现在引用计数都是1。

现在让A和B互相引用,两个对象的引用计数都增加了1,都变成了2。

执行[A release];[B  release];main函数就释放了自己的对象,但A和B互相引用,引用计数都还是1。

这时A和B将无法释放,因为要想释放A必须先释放B,在B的dealloc方法中再释放A。

同理,要想释放B必须先释放A,在A的dealloc方法中再释放B。

所以这两个对象将一直存在在内存中而不释放,这就是循环引用问题。

2.3 解决方案

一般的可以将短生命周期的引用属性设置为assign。或者A,B都设置为assign

循环引用示例:

// Person.h
@class Car

@interface Person

@property(noatomic, retain) Car* car; 

@end
// Person.m
#import "Person.h"

@implementation Person

- (void)dealloc
{
	[_car release];
	_car = nil;

	[super dealloc];
}

@end
// Car.h
@class Person

@interface Car

@property(noatomic, retain) Person* person; 

@end
// Car.m
#import "Car.h"

@implementation Car

- (void)dealloc
{
	[_person release];

	[super dealloc];
}

@end
// main.m
#import "Car.h"
#import "Person.h"

int main()
{
	Person* person = [[Person alloc] init];// person 1
	Car* car = [[Car alloc] init];// car 1
	person.car = car;// car 2
	car.person = person;// person 2
	[car release];// car 1
	[person release];// person 1

	return 0;
}

解决示例:

// Car.h
@class Person

@interface Car

@property(noatomic, assign) Person* person; 

@end
// Car.m
#import "Car.h"

@implementation Car

- (void)dealloc
{
	[super dealloc];
}

@end

// main.m
#import "Car.h"
#import "Person.h"

int main()
{
	Person* person = [[Person alloc] init];// person 1
	Car* car = [[Car alloc] init];// car 1
	person.car = car;// car 2
	car.person = person;// person 1
	[car release];// car 1
	[person release];// person 0,car 0

	return 0;
}
时间: 2024-11-08 22:12:04

iOS复习笔记7:循环引用问题的相关文章

IOS中Block的循环引用

@interface DemoObj() @property (nonatomic, strong) NSOperationQueue *queue; @end @implementation DemoObj - (instancetype)init { self = [super init]; if (self) { self.queue = [[NSOperationQueue alloc] init]; } return self; } - (void)dealloc { NSLog(@"

iOS 容易引“起循环引用”的三种场景

笔者在阅读中总结了一下,在iOS平台容易引起循环引用的四个场景: 一.parent-child相互持有.委托模式 [案例]:   @interface FTAppCenterMainViewController () { } @property(weak,nonatomic) UITableView* myTableView; @end 这里面的myTableView就使用了weak修饰符. 1 @property (nonatomic, weak)  id<ftactionsheetdeleg

iOS开发——Block引起循环引用的解决方案

内存问题始终是软件开发中的头等大事,iOS开发中也不例外,在面试中也是必问的问题.今天我们主要来讲讲Block中涉及的循环引用问题.当我们自己一开始写代码的时候,可能会大量在block中使用self,但是当看到别人优秀的代码的时候,发现别人常常不是用self,而使用weakSelf. 为什么呢?本文的示例代码上传至 https://github.com/chenyufeng1991/Block_WeakSelf . 首先我先来说说内存管理的原则: 1.默认使用strong,可选weak.stro

iOS 里面 NSTimer 防止 循环引用

使用NSTimer的类 #import "TBTimerTestObject.h" #import "TBWeakTimerTarget.h" @interface TBTimerTestObject() @property (nonatomic, weak) NSTimer *timer; @end @implementation TBTimerTestObject - (void)dealloc { NSLog(@"timer is dealloc&q

iOS复习笔记9:ARC功能

一 ARC简介 ARC是编辑器的一种功能. 它会把alloc出来的对象,自动release. 它把使用retain属性的变量,在dealloc中自动生成release: 在新建项目时选中ARC功能后,不允许调用: retain retainCount release autorelease [super dealloc] 二 ARC的判断准则 1 准则:只要没有强指针对象,就会销毁对象 2 指针分两种: 1 强指针: __strong,默认情况下所有的指针都是强指针 2 弱指针: __weak,

iOS复习笔记1:HelloWorld项目

2012年10月到2013年5月期间,一直都做iOS开发,后来开始做用cocos做游戏开发. 过去了那么久,复习一下以前学的东西. 一 新建工程 打开Xcode,选择File>Project>Single View Application,然后输入工程名HelloWolrd,选择保存路径. 创建完成之后保存,如图: 二 运行 单击上图左上角的三角形按钮,程序久可是运行了,以下界面一闪而过: 然后出现: 这就是用模拟器运行程序啦:如果闲模拟器太大,看不清楚,可以点击模拟器,然后Window>

IOS中的block 循环引用和retain cycle (经典)

retain cycle 的产生 说到retain cycle,首先要提一下Objective-C的内存管理机制. 作为C语言的超集,Objective-C延续了C语言中手动管理内存的方式,但是区别于C++的极其非人道的内存管理,Objective-C提出了一些机制来减少内存管理的难度. 比如:内存计数. 在Objective-C中,凡是继承自NSObject的类都提供了两种方法,retain和release.当我们调用一个对象的retain时,这个对象的内存计数加1,反之,当我们调用relea

iOS复习笔记8:autorelease详解

一 概念 iOS在程序在运行的过程中,会创建很多个释放池,自动释放池以栈的形式存放的(先进后出). 对象调用autorelease时,会被放入栈顶的自动释放池中. 当自动释放池销毁时,会对池的所有对象发送一次release消息: 所以发送autorelease之后引用计数不会立即-1. autorelease返回对象本身. 二 实例 // Person.h @interface Person @property(nonatomic, assign) int age; @end // Person

2015 IOS 学习笔记 for循环 方法练习 ——蓝懿教育

今天学习了for循环以及方法,内容有些复杂,不过万变不离其宗 在以后的学习中容易掌握,因为涉及范围广阔,使用率高.所以多加练习后会掌握. ————————for循环—————————— for循环概念: for循环编程语言中的语句之一,用于循环执行.for循环是开界的,它的一般形式为: for(; <<span se-mark="1">条件表达式>; ) 语句: 初始化总是一个赋值语句, 它用来给循环控制变量赋初值: 条件表达式是一个关系表达式, 它决定什么时候