文档章节

自动释放池

Heisenbean
 Heisenbean
发布于 2014/09/16 02:43
字数 1365
阅读 227
收藏 0

什么是自动释放池?                                                                               

在OC中也有一种内存自动释放的机制叫做“自动引用计数”(或“自动释放池”),与C#、Java不同的是,这只是一种半自动的机制,有些操作还是需要我们手动设置的。自动内存释放使用@autoreleasepool关键字声明一个代码块,如果一个对象在初始化时调用了autorelase方法,那么当代码块执行完之后,在块中调用过autorelease方法的对象都会自动调用一次release方法。这样一来就起到了自动释放的作用,同时对象的销毁过程也得到了延迟(统一调用release方法)。

自动释放池的使用                                                                                      

sample code:

@autoreleasepool{

}


左大括号开始表示释放池开始,右大括号表示释放池结束,所以当调用autorelease方法后只是把对象放入自动释放池而已,计数器是没有变化的,即没有做release操作,而是当遇到}才会release


一般在创建对象的时候连着alloc一起使用,因为autorelease是返回对象本身的,返回类型是id

Person *p = [[[Person alloc] init] autorelease];

意思就是把person这个对象放到一个自动释放池里,当释放池被销毁的时候,池子里的对象将会做一次release操作

autorelease好处:

1.不用关心对象的释放时间

2.不用关心release的调用时间

autorelease使用注意:

1.占用内存大的对象不宜用,因为无法控制release的调用时间

2.占用内存小的对象用的话也没有多大的效果

3.系统自带的方法中,如果不包含alloc,new,copy,那么这些方法返回的对象都是已经autorelease过的,比如:[NSString stringWithFormat:….];[NSDate date];

autorelease的错误用法:

1.在创建对象,alloc的时候调用了autorelease,又调用release的话就会出现野指针错误

 

 @autoreleasepool {
        Person *p= [[[Person alloc] init] autorelease];
        [p release];
    }

2.连续多次调用autorelease也会出现野指针错误

 @autoreleasepool {
        Person *p= [[[[Person alloc] init] autorelease] autorelease];
    }

把autorelease以类方法的形式重写可以简化主函数中的代码量:

注意:重写autorealese创建对象的时候不要直接使用类名,self

如果觉得释放池这样写冗长的话,可以把autorelease以类方法的形式写在类中

先在.h文件中声明这个person方法,然后在.m文件中做如下实现

+(id)person
{
    return [[[Person alloc] init] autorelease];
}

那么头文件中的释放池中只需

 @autoreleasepool {
        // Person *p= [[[Person alloc] init] autorelease];
        Person *p = [Person person];// 这一行就可以代替上面那段长代码
        p.age = 100;
    }

类方法还可以写成带参数的形式,在类的.m文件中做如下实现:

@implementation Person
+ (id)person
{
    return [[[self alloc] init] autorelease];
}
+(id)personWithAge:(int)age
{
    Person *p = [self person];    // 此处的person指向第二行定义的person类方法
    p.age = age;
    return p;
}
@end

 

主函数中

@autoreleasepool {
       // Person *p = [Person person];
      //  p.age = 100;
        Person *p = [Person personWithAge:100]; // 这一句可以代替上面两句
    }


自动释放池简单总结:

1.autorelease方法不会改变对象的引用计数器,只是将这个对象放到自动释放池中

2.自动释放池实质是当自动释放池销毁后调用对象的release方法,不一定就能销毁对象(例如如果一个对象的引用计数器>1则此时就无法销毁)

3.由于自动释放池最后统一销毁对象,因此如果一个操作比较占用内存(对象比较多或者对象占用资源比较多),最好不要放到自动释放池或者考虑放到多个自动释放池

4.OC中类库中的静态方法一般都不需要手动释放,内部已经调用了autorelease方法

循环引用                                                                                               

@class的作用:仅仅告诉编译器,某个名称是一个类,用来解决循环引用的问题

如果想要使用类中的成员变量,还需要#import这个类

 

开发中引用一个类的规范

1..h文件中用@class来声明

2..m文件中用#import来包含类的所有东西

 

当出现两个类中都需要retain的时候,就是循环引用的时候

应该一端用retain,另一端用assign

ARC总结                                                                                      

ARC判断标准

ARC的判断标准:只要没有强指针对象,就会释放对象

指针分两种:

1.强指针:默认情况下,所有的指针都是强指针__strong

2.弱指针:__weak,弱指针指向的对象被回收后,弱指针会自动变为nil指针,不会引发野指针错误

强弱指针使用注意:

1. 不能调用release、retain、autorelease、retainCount

2. 可以重写dealloc,但是不能调用[super dealloc]

3. @property : 想长期拥有某个对象,应该用strong,其他对象用weak

         *strong:成员变量是强指针,相当于retain,适用于OC对象类型

         *weak: 成员变量是弱指针,相当于之前的assign适用于OC对象类型

         *assign:适用于非OC对象

4. 其他基本数据类型依然用assign,以前写的retain都改写成strong

5. 两端互相引用时,一端用strong、一端用weak


ARC和非ARC之间的转换:

不使用ARC:-fno-objc-arc

使用ARC:-f-objc-arc

© 著作权归作者所有

上一篇: block、Protocol
下一篇: 内存管理
Heisenbean
粉丝 0
博文 16
码字总数 20720
作品 0
漯河
高级程序员
私信 提问
OC学习篇之---数组对象的引用计数问题和自动释放池的概念

之前一片文章中我们介绍了OC中的两个关键字@property和@synthesize的使用的使用: http://blog.csdn.net/jiangwei0910410003/article/details/41925967 今天我们来看一下OC中数组对象在是如何...

jiangwei0910410003
2014/12/14
0
0
IOS高级教程1:处理1000张图片的内存优化

转载请保留以下原文链接: http://my.oschina.net/taptale/blog/91894 一、项目需求 在实际项目中,用户在上传图片时,有时会一次性上传大量的图片。在上传图片前,我们要进行一系列操作,比...

一叶博客
2012/11/26
18.1K
10
object-c 自动释放池

学习object-c到内存管理章节, 上面说明是: 自动释放池其实并不包含实际的对象本身,仅仅是对释放的对象的应用. 而在baidu上看到另一个教程是:自动释放池,它是一个存放实体的池,这些实体可能是...

fcsong000833
2013/01/21
577
1
深入理解 Cocos2d-x 内存管理

如果 Cocos2d-x 内存管理浅说 做为初步认识,而 Cocos2d-x 内存管理的一种实现做为进阶使用,那么本文将详细的分析一下 Cocos2d-x 的内存管理的设计实现和原理。知其然,知其所以然 ~或者说:...

xuhong
09/29
0
0
ios iphone开发-内存管理

关于所有权 所有权是iPhone内存管理的核心思想,对象的所有者负责在使用完对象后进行释放。一个对象可以有多个所有者,当它没有所有者时将被设置为取消分配(deallocation)。 创建对象时,所...

长平狐
2012/10/09
133
0

没有更多内容

加载失败,请刷新页面

加载更多

前端面试题汇总

一. HTML常见的兼容性 1.HTML5 标签在低版本浏览器不兼容 解决办法:使用html5shiv库,引入下列语句 <!--[if lte IE 8]> <script src="https://cdn.bootcss.com/html5shiv/r29/html5.js"></sc......

蓝小驴
23分钟前
5
0
OSChina 周四乱弹 —— 我气的脸都黑了!

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 小小编辑推荐《Red Battle》- 高橋李依 / 豊崎愛生 《Red Battle》- 高橋李依 / 豊崎愛生 手机党少年们想听歌,请使劲儿戳(这里) @丶Lion ...

小小编辑
36分钟前
432
19
找OSG教程, B站就有

https://www.bilibili.com/video/av64849038?from=search&seid=11632913960900279653

洛克人杰洛
58分钟前
5
0
学习记录(day07-Vue组件、自定义属性、自定义事件)

[TOC] 1.1.1什么是组件 一个vue文件就是一个组件 组件将html标签/css样式/对应JS打包成一个整体,也可以理解钻进一个具有样式和特效的自定义标签。 一、编写组件(提供方)<template> <di...

庭前云落
今天
5
0
使用Prometheus监控SpringBoot应用

通过之前的文章我们使用Prometheus监控了应用服务器node_exporter,数据库mysqld_exporter,今天我们来监控一下你的应用。(本文以SpringBoot 2.1.9.RELEASE 作为监控目标) 编码 添加依赖 使...

JAVA日知录
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部