IOS面试题目-----oc 是如何管理内存的《Z》

一 基本原理

Objective-C的内存管理机制与Java那种全自动的垃圾回收机制是不同的,它本质上还是C语言中的手动管理方式,只不过稍加了一些自动方法.

1,OC采用了引用计数(retain count)对对象内存进行管理,例如,某个对象alloc了,那么这个对象的引用计数就加1,retain时加1,当对象不需要用时就需要销毁对象,释放内存,需要对象调用release方法,release会让引用计数减1,只有引用计数消失,相当于等于0,对象才会调用dealloc真正销毁这个对象.

OC的对象在使用完成后不能自动销毁,一定要记得释放内存.

Class *obj = [[Class alloc]init];//对象obj引用计数加1

Class *obj2 = obj;//两个对象指向同一块内存

[obj hello];

[obj release];//对象被销毁

[obj2 hello];//错误,obj2指向的内存不存在了

[obj2 release];//[obj release]之后,obj2是个无效指针,没有内存,不能调用方法.

注:dealloc是自动调用,一定不能手动调用.指针赋值不会使引用计数加1.

2,OC中引入了autorelease pool(自动释放对象池),在遵守一些规则的情况下,可以自动释放对象.新生成的对象,只要调用autorelease就行了,无需再调用release.

autorelease pool需要手动建立,在新建一个项目时,xcode会自动创建一个,NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];NSAutoreleasePool 内部包含一个数组(NSMutableArray),用来保存声明为autorelease的所有对象,一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中去.

NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数组,release数组中的每一个成员.如果此时数组中成员的retain count为1那么release之后,retain count为0,对象正式销毁,如果此时数组中成员的retain count大于1,那么release之后,retain count大于0,对象依然没有被销毁,内存就会泄露,所以一定要注意内存管理规则(见下).

注:什么情况下创建自动释放对象池?1)在多线程里面要自己创建.2)如果代码里面有大量临时变量时最好创建自动释放对象池.

for(int i=0;i<100;i++){

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

for(int j=0;j<100000;j++){

[NSString stringWithFormat:@"123455666"];//产生的对象是autorelease的.

}

[pool release];

}

二、规则

 1 谁创建,谁释放。如果通过alloc、new或copy来创建一个对象,那么你必须调用autorelease或在使用完成时调用release,不是你创建的,就不用你去释放。

2  除了alloc,new或copy之外的方法创建的对象在内部都被声明了autorelease。如,[UIButton buttonWithType:].

3  谁retain,谁release,只要你调用了retain,无论这个对象是如何生成的,你都要调用release.

三、范式

 1 创建一个对象

Class *obj = [[Class alloc] init];

2 创建一个自动释放对象

Class *obj = [[[Class alloc] init]autorelease];

3 指针赋值给另一个指针

Class *obj2 = obj1;

[obj2 retain];

[obj2 release];

4 在一个函数中创建并返回对象,需要把这个对象设置为autorelease

- (Class *)fun{

Class *obj = [[[Class alloc] init] autorelease];

return obj;

}

5 在子类的dealloc方法中调用基类的dealloc方法

- (void)dealloc{

 ……

  [super dealloc];

}

  对于属性里的内存机制请参考属性详细说明。

注:不要过度依赖retaincount,有时候内部实现并不像表面那样,计数不会换我们看到的那样,例如

MovieViewController *movie = [[MovieViewController alloc]init];

NSLog(@"===%d",[movie.view retainCount]);//3

NSLog(@"===%d",[movie.view retainCount]);//4

NSLog(@"===%d",[movie.view retainCount]);//5

时间: 2024-10-10 11:21:49

IOS面试题目-----oc 是如何管理内存的《Z》的相关文章

OC中手动管理内存

//1.对象在完成创建的同时,内部会自动创建一个引用计数器,这个计数器,是系统用来判断是否回收对象的唯一依据,当我们的引用计数retainCount = 0的时候,系统会毫不犹豫回收当前对象 //2.[对象 release]  reatinCount - 1 //3.[对象 retain]   reatinCount + 1 ,返回self //4.我们的引用计数retainCount = 0的 对象就被销毁了 //5.dealloc函数,当一个对象要被销毁的时候,系统会自动调用dealloc函

iOS开发之oc(十一)--内存管理MRC

掌握内容 >理解内存管理的原理 >掌握手动内存管理MRC >掌握内存管理在实际工程中的使用 (一) 1.理解部分 1.1内存管理 (传统内存管理demo) 1.1.1内存管理做了一件什么事? 内存管理就是确保开辟的堆空间得到正确的释放 如果堆空间没有释放,称为内存泄露 使用已释放的堆空间,称为提前释放 重复释放同一个空间,称为重复释放 1.1.2传统内存管理的困境 (1)当我们要释放一个堆,首先要确定使用这个堆的指针,都访问完毕,避免提前释放. (2)释放指针指向的堆空间,首先要确定那些

最基础、最全面的iOS面试题目

OC的理解与特性 OC作为一门面向对象的语言,自然具有面向对象的语言特性:封装.继承.多态.它既具有静态语言的特性(如C++),又有动态语言的效率(动态绑定.动态加载等).总体来讲,OC确实是一门不错的编程语言, Objective-C具有相当多的动态特性,表现为三方面:动态类型(Dynamic typing).动态绑定(Dynamic binding)和动态加载(Dynamic loading).动态——必须到运行时(run time)才会做的一些事情. 动态类型:即运行时再决定对象的类型,这

(转)iOS面试题目

1.Object-C有多继承吗?没有的话用什么代替?cocoa 中所有的类都是NSObject 的子类 多继承在这里是用protocol 委托代理 来实现的 你不用去考虑繁琐的多继承 ,虚基类的概念. ood的多态特性 在 obj-c 中通过委托来实现. 2.Object-C有私有方法吗?私有变量呢? objective-c – 类里面的方法只有两种, 静态方法和实例方法. 这似乎就不是完整的面向对象了,按照OO的原则就是一个对象只暴露有用的东西. 如果没有了私有方法的话, 对于一些小范围的代码

ios面试题目(一)

1.多线程在实际现实中有哪些应用?(网络操作和大量图片处理不算) 通常耗时的操作都会放在子线程里处理,然后再回到主线程来显示.下面举几个例子: 我们要从数据库提取数据还要将数据分组后显示,那么就会开个子线程来处理,处理完成后才去刷新UI显示. 拍照后,会在子线程处理图片,完成后才回到主线程来显示图片.拍照出来的图片太大了,因此要做处理. 音频.视频处理会在子线程来操作 文件较大时,文件操作会在子线程中处理 做客户端与服务端数据同步时,会在后台闲时自动同步 2.如果app比较大,怎么样减少app的

ios面试总结-

一 C语言方法的知识 1: const  static  voilite 修辞变量各代表什么意思? const  修辞的变量为常量,常量是不容许修改.  static  修辞的变量为静态变量,在内存中只被创建一次(如UItableView 中创建Cell的代理方法 用会用到静态变量标识Cell) Volatile定义变量为一个共享变量 2: static 的作用 在类中 static  修饰的变量属于整个类的所有,对类的所有对象共享一份 在类中static   修辞的方法属于这个类所有,该方法不

iOS开发——面试篇&amp;OC基本语法总结(面试)

OC基本语法总结(面试) C和OC对比 OC中主要开发在什么平台上的应用程序? 答:可以使用OC开发Mac OS X平台和iOS平台的应用程序 OC中新增关键字大部分是以什么开头? 答:OC中新增关键字大部分是以@开头 OC中新增加了那些数据类型? 答: Block类型 指针类型(Class, id类型) 空类型 特殊类型(SEL, nil) 面向对象特性是什么? 答:继承性,封装性,多态性 import和#include有什么区别? 答:import 的功能和 include一样, 是将右边的

C C++ OC iOS面试重点问题(一)

C C++ OC iOS面试重点问题(一) 1.字符串常量需要加\0 2.逻辑运算 位操作(经典:实现两个数的交换) 3.关键字 4.引用和指针的区别和联系 5.如何引用一个已经定义过的全局变量?  答:可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变变量,假定你将那个变量写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错. 5.extern关键字的用法? 答:ext

OC加强(一)之内存管理

1.为什么要进行内存管理? 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存 较多时,系统就会发出内存警告,一个app可用的内存是被限制的,如果一个app使用的内存超 过20M,则系统会向该app发送Memory Warning消息.收到此消息后,需要回收一些不需要再 继续使用的内存空间,比如回收一些不再使用的对象和变量等,否则程序会崩溃. 这里首先要解释一个常识概念:内存,存储空间,各自的功能? 内存:我们一般说的手机内存其实是指运行内存,,简称运存,即