文档章节

4.内存管理

海风OSCHINA
 海风OSCHINA
发布于 2013/12/29 14:41
字数 945
阅读 33
收藏 0

一、IOS内存管理

1、内存管理范围:任何继承了NSObject的对象,对基本数据类型无效。

2、内存管理原理:

(1)每个对象内部保存了一个与之相关联的整数,称为引用计数器。

(2)当使用alloca、new或者copy创建一个对象时,对象的引用计数器被设置为1.

(3)当给对象发送一条retain消息时,引用计数器加。

(4)当给对象发送一条release消息时,引用计数器减1。

(5)当对象的引用计数器为0时,该对象将被销毁,其占用的内存将被系统回收,OC也会自动向对象发送一条dealloc消息。一般会重写dealloca方法来释放相关资源,一定不要直接调用dealloca方法。

(6)可以给对象发送retainCount消息获得当前的引用计数器的值。


用于理解内存管理的实例:

1.Book类:

#import <Foundation/Foundation.h>
@interface YtsBook : NSObject
{
int _ID;
}
@property int ID;
-(id)initWithID:(int)_ID;
@end

#import "YtsBook.h"
@implement YtsBook:
@synthesize ID = _ID;
-(id)initWithID:(int)ID:
{
	_ID=ID;
}
@end

2.Student类:

#import <Foundation/Foundation.h>
//#import "YtsBook.h"
@class YtsBook;	//@class声明需用到YtsBook类
@interface YtsStudent : NSObject
{
	YtsBook *_book;
}
@property YtsBook *book;
@end

#import "YtsStudent.h"
#import "YtsBook.h"
@implement YtsStudent:
@synthesize book = _book;
-(void)setBook:(Book *)book		//在OC2.0以上,一般都是用@property的声明列表来代替这种方法。
{
	if(_book!=book)	//加上判断,预防重复复制
	{
		[_book release];	//释放旧值
		_book = [book retain];	//先retain,再赋值
	}
}

-(void)dealloc
{
	[_book release];	//由于赋值时做了retain,这里要负责将其release
	[super dealloc];
}

3. main.m

int main (int argc, const char * argv[]) 
{
	@autoreleasepool{
		YtsStudent *student = [[YtsStudent alloc] init];	//student引用计数器为1
		YtsBook *book = [[YtsBook alloc] initWithID:100];	//book引用计数器为1.
		student.book = book;	//book引用计数器为2
		[book release];	//book引用计数器为1
		[student release];	//此时book引用计数器为0,student引用计数器为0
	}
}

二、内存自动释放

1、自动释放池原理

(1)autorelease pool的真名是NSAutoreleasePool,在新建一个项目时,编译器会默认创建一个自动释放池。

(2)NSAutoreleasePool内部包含一个可变数组(NSMutableArray),用于保存声明为autorelease的对象。

(3)如果一个对象声明为autorelease,则系统就将这个对象加入到该数组中。

(4)当NSAutoreleasePool自身在销毁时,会遍历一遍该数组,release数组中的每一个成员。

实例:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
YtsStudent *student = [[[YtsStudent alloc] init] autorelease];	//设置为autorelease
YtsBook *book = [[[Book alloc] init] autorelease];	//设置为autorelease
student.book = book;
[pool release];

2、自动释放池做法

因为标记为autorelease的对象只有在自动释放池被销毁时才被release,当有大量标记为autorelease的对象时,就会存在内存故障。 所以我们经常手动定义一个NSAutoreleasePool,通过控制该池的销毁达到及时释放内存的目的。

 创建自动释放池的方法为:NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

 销毁自动释放池的方法为:[pool release];

 3.当一个对象被声明为autorelease时,它将被加入到最新创建的自动释放池中。


三、内存管理口诀

 1. 通过alloc、new或copy创建的对象,那么必须调用release或autorelease。

 如果在类的某函数中alloc生成一个对象,那么必须在类的dealloc方法中release该对象,或者alloc和init该对象时就声明autorelease。

 注意:实现NSCopying的initWithZone方法里边,不要对创建的对象做autorelease或者release。

 2. 除了alloc、new或copy之外的方法创建的系统自带的类的对象都已被声明了autorelease,无需在进行release。


© 著作权归作者所有

海风OSCHINA
粉丝 1
博文 4
码字总数 3053
作品 0
广州
部门经理
私信 提问
海思方案中地址空间的分配与使用

1、DDR内存管理说明 (1)所有DDR内存中,一部分由操作系统管理,称为OS内存;另一部分由MMZ模块管理,供媒体业务单独使用,称为MMZ内存。 (2)OS内存起始地址为0x80000000,内存大小可通过...

天糊土
2018/09/22
0
0
BSS段和数据段

内存分段(英语:Memory segmentation),一种电脑内存的管理技术,它将电脑的主内存分成许多区段(segment或sections)。当处理器要进行内存定址时,会使用一个数值,这个数值包括了某个区段...

壶漏子
2016/12/10
11
0
Virtual Machine

虚拟机 关于内存 CPU通过总线来管理内存, 总线分为3种 控制总线: 指定对内存进行的是读还是写操作 地址总线: 用来表示内存中的地址, 一根地址电线对应一个0|1bit, 如果有4根线, 则CPU对内存的...

megachen
2018/06/08
0
0
深入理解Linux内存管理-之-目录导航

转自:https://blog.csdn.net/gatieme/article/details/52384965 1 内存描述 2 页表管理 3 初始化内存管理

zwfgogo
2018/04/20
0
0
Memcached与Redis(三)

3. Memcached和Redis关键技术对比 作为内存数据缓冲系统,Memcached和Redis均具有很高的性能,但是两者在关键实现技术上具有很大差异,这种差异决定了两者具有不同的特点和不同的适用条件。下...

liujing07
2018/06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

VMware vSphere ESXi主机的访问控制

在vShpere中,访问ESXi主机的途径很多,如下: ESXi DCUI ESXi Shell ESXi SSH ESXi Host Client vCenter --> vSphere web client / vSphere Client VMware vSphere ESXi主机的访问控制,除了......

大别阿郎
26分钟前
3
0
大神讲解CGI、FastCGI和PHP-FPM关系图解

参考资料 概念了解:CGI,FastCGI,PHP-CGI与PHP-FPM:http://www.nowamagic.net/librarys/veda/detail/1319 php中fastcgi和php-fpm是什么东西:https://www.zybuluo.com/phper/note/50231 ......

网络小虾米
35分钟前
3
0
《DNS攻击防范科普系列3》 -如何保障 DNS 操作安全

引言 前两讲我们介绍了 DNS 相关的攻击类型,以及针对 DDoS 攻击的防范措施。这些都是更底层的知识,有同学就来问能否讲讲和我们的日常操作相关的知识点,今天我们就来说说和我们日常 DNS 操...

Mr_zebra
36分钟前
3
0
zk中ServerCnxn

实现接口Stats, Watcher 内部类 DisconnectReason CloseRequestException EndOfStreamException(流关闭) 属性 方法 getSessionTimeout 获取session失效时间 sendResponse 发送回复数据 se......

writeademo
41分钟前
3
0
如何将 Redis 用于微服务通信的事件存储

来源:Redislabs 作者:Martin Forstner 翻译:Kevin (公众号:中间件小哥) 以我的经验,将某些应用拆分成更小的、松耦合的、可协同工作的独立逻辑业务服务会更易于构建和维护。这些服务(也...

中间件小哥
44分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部