文档章节

IOS第六天——Obj-C的内存管理初步认识

我爱睡觉
 我爱睡觉
发布于 2017/06/24 17:38
字数 1166
阅读 1
收藏 0

转:http://blog.csdn.net/jeepxiaozi/article/details/8821747

今天是学习IOS开发的第六天,那么因为看的比较快,所以现在应该到了IOS开发中的重中之重了,那就是内存管理。

Obj-C中的内存管理不同于C语言式的完全手动管理方式,malloc和free操控内存,也不同于GC语言(例如java&ruby等)的自动回收方式,在Obj-C中的内存管理方式采用的是比较折中的方式,也就是手动和半自动结合,采用自动对象释放池进行自动管理或者采用引用计数值进行手动管理。

1.      引用计数值

至于为什么要进行内存管理,这里我想大家应该基本了解了,即使我这种不太了解底层的码畜都知道一些,那么内存管理就是CPU内存资源的分配和回收,良好的内存管理机制在于尽量控制CPU内存资源的浪费。

Obj-C中语言中引用计数值的管理方式,对象每次alloc1次计数值为1同时获得内存,每retain 1次计数值加1,每release 1次计数值减1,直到计数值为0的时候,对象就会被销毁,主要的操控接口如下:

         Alloc、allocWithZone、new(并且初始化)——为对象分配内存,计数值+1,返回实例

         Release——计数值-1

         Retain——计数值+1

         Copy、mutableCopy——复制一个实例,计数值为1,返回实例,所得到的对象是一个全新的对象

         Autorelease在当前的上下文的autoreleasePool栈顶添加对象,由于它的引入使Obj-C的内存管理方式由全手动上升为半自动。

那么我们来看一段代码实例,演示下内存的计数值管理

  1. #import <Foundation/NSObject.h>  
  2. #import <Foundation/NSAutoreleasePool.h>  
  3. #import <Foundation/NSString.h>  
  4. #import <Foundation/NSArray.h>  
  5. #import <Foundation/NSValue.h>  
  6. Int main (int argc, char * argv[])  
  7. {  
  8.          NSAutoreleasePool* pool=[[NSAutoreleasePool alloc] init];  
  9.          NSNumber*myInt=[[NSNumber alloc] initWithInt: 100];//实例化一个NSNumber对象myInt,并且调用alloc方法,其引用计数值加1,为+1  
  10.          NSLog(@”myInt retain count=%lx”, (unsigned long) [myInt retainCount]);  
  11.          //输出myInt的引用计数  
  12.          [myInt retain];//myInt对象调用retain方法,引用计数值再+1,为+2  
  13.          NSLog(@”myInt retain count after retain=%lx”, (unsigned long) [myInt retainCount]);  
  14.          //输出myInt的引用计数  
  15.          [myInt release];//myInt对象调用release方法,引用计数值-1,为+1,此时myInt对象仍然存在,并未释放  
  16.          NSLog(@”myInt retain count after release=%lx”, (unsigned long) [myInt retainCount]);  
  17.          //输出myInt的引用计数值  
  18.          NSNumber* secant=[myInt copy];//myInt调用copy方法,返回引用计数为1的实例,此时secInt的引用计数值为1,myInt的引用计数值不变  
  19.          NSLog(@” secant retain count after copy=%lx”, (unsigned long) [secant retainCount]);  
  20.          [secInt release];//secInt调用release方法,引用计数-1,为0,secInt对象被彻底释放  
  21.          [myInt release];//myInt对象调用release方法,应用计数-1,为0,myInt对象被彻底释放  
  22.          [poold rain];  
  23.          return0;  
  24. }  


程序的最终输出结果如下:

myInt retain count=1

myInt retain count after retaine=2

myInt retain count after release=1

secInt retain count after copy=1

 

上述这段代码演示了计数机制是如何工作的,简单的规则就是,alloc和retain会让对象引用计数+1,release会让对象的引用计数-1,而copy对象则是只会将新的对象的引用计数+1,所以简单的规避内存泄露的一个方法就是有多少个alloc和retain,就要有多少个相应的release。

2.      对象释放池

有时候程序代码可能会返回临时变量,Obj-C提供了一种比较优雅的方式,就是延迟释放,即对象自动释放池。

  1. NSAutoreleasePool*pool=[[NSAutoreleasePool alloc] init];//声明对象以及对对象进行操作  
  2. [pool drain];//释放自动释放池  

当pool被建立以后,系统会自动生成一个数组,在当前上下文中有变量被置为autorelease的时候,系统就会把此变量加入数组当中,然后在[pool drain]时变量的内存计数值-1,因此设置为autorelease的变量不要手动释放,除非你retain过。

 

那么今天我们就是先简单的了解下Obj-C的内存管理,其实这个总的来说并不是特别复杂,但是它却是重中之重,起码在我看来,周围已经遇到好些个工程师因为内存泄露的问题导致程序产生比较严重的bug了,那么随着学习的不断深入,我们会对这块儿有更深入的了解和体会。

2013年4月18日,Eric.Tang 记

本文转载自:http://blog.csdn.net/zhangmiaoping23/article/details/42913817

我爱睡觉
粉丝 3
博文 2120
码字总数 0
作品 0
南昌
私信 提问
那些在学习iOS开发前就应该知道的事(part 2)

英文原文:Things I wish I had known before starting iOS development—Part 2 如果你还没读这篇文章的第一部分,请先读完了再来看第二部分。 那些在学习iOS开发前就应该知道的事(part 1)...

TomatosX
2015/06/12
140
0
IOS内存常见问题与内存检查工具

iOS平台内存常见问题 作为iOS平台的开发者,是否曾经为内存问题而苦恼过?内存莫名的持续增长,程序莫名的crash,难以发现的内存泄漏,这些都是iOS平台内存相关的常见问题;本文将会详细介绍...

长平狐
2012/10/25
592
0
iOS 编写高质量Objective-C代码(五)

级别: ★★☆☆☆ 标签:「iOS」「内存管理」「Objective-C」 作者: MrLiuQ 审校: QiShare团队 前言: 这几篇文章是小编在钻研《Effective Objective-C 2.0》的知识产出,其中包含作者和小...

QiShare
2018/09/05
0
0
那些在学习iOS开发前就应该知道的事(part 1)

英文原文:Things I wish I had known before starting iOS development—Part 1 设计师设计出来了一个不错的引导界面,然而当我看到设计稿的时候,我们的app也没几天就要上线了。这个界面模...

TomatosX
2015/06/12
111
0
[C++][IO]fstream用法

fstream用法 1. 打开文件 在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是: void open(const char* filename,int mode,int access); 参数: filename:  要打开的文件...

guitar_zp
2011/08/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程。 一、ThreadPoolTaskExecutor 本文采用 Executors 的工厂...

CREATE_17
今天
5
0
CSS盒子模型

CSS盒子模型 组成: content --> padding --> border --> margin 像现实生活中的快递: 物品 --> 填充物 --> 包装盒 --> 盒子与盒子之间的间距 content :width、height组成的 内容区域 padd......

studywin
今天
7
0
修复Win10下开始菜单、设置等系统软件无法打开的问题

因为各种各样的原因导致系统文件丢失、损坏、被修改,而造成win10的开始菜单、设置等系统软件无法打开的情况,可以尝试如下方法解决 此方法只在部分情况下有效,但值得一试 用Windows键+R打开...

locbytes
昨天
8
0
jquery 添加和删除节点

本文转载于:专业的前端网站➺jquery 添加和删除节点 // 增加一个三和一节点function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(".triple-panel-con......

前端老手
昨天
8
0
一、Django基础

一、web框架分类和wsgiref模块使用介绍 web框架的本质 socket服务端 与 浏览器的通信 socket服务端功能划分: 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn... 根据用户访问...

ZeroBit
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部