面试题 For BearLiniOS_Interview_2017iOS学习笔记2017-3-29

可能碰到的iOS笔试面试题(6)--内存管理

2016-05-04  本文已影响4653人  b485c88ab697

内存管理

ARC处理原理

ARC是Objective-C编译器的特性,而不是运行时特性或者垃圾回收机制,ARC所做的只不过是在代码编译时为你自动在合适的位置插入release或autorelease,只要没有强指针指向对象,对象就会被释放。

前端编译器会为“拥有的”每一个对象插入相应的release语句。如果对象的所有权修饰符是__strong,那么它就是被拥有的。如果在某个方法内创建了一个对象,前端编译器会在方法末尾自动插入release语句以销毁它。而类拥有的对象(实例变量/属性)会在dealloc方法内被释放。事实上,你并不需要写dealloc方法或调用父类的dealloc方法,ARC会自动帮你完成一切。此外,由编译器生成的代码甚至会比你自己写的release语句的性能还要好,因为编辑器可以作出一些假设。在ARC中,没有类可以覆盖release方法,也没有调用它的必要。ARC会通过直接使用objc_release来优化调用过程。而对于retain也是同样的方法。ARC会调用objc_retain来取代保留消息。

虽然前端编译器听起来很厉害的样子,但代码中有时仍会出现几个对retain和release的重复调用。ARC优化器负责移除多余的retain和release语句,确保生成的代码运行速度高于手动引用计数的代码。

下面关于Objective-C内存管理的描述错误的是

A 当使用ARC来管理内存时,代码中不可以出现autorelease
B autoreleasepool 在 drain 的时候会释放在其中分配的对象
C 当使用ARC来管理内存时,在线程中大量分配对象而不用autoreleasepool则可能会造成内存泄露
D 在使用ARC的项目中不能使用NSZone

MRC文件在ARC工程混合编译时,需要在文件的Compiler Flags上添加什么参数

A -shared
B -fno-objc-arc
C -fobjc-arc
D -dynamic
参考答案:B

什么情况使用 weak 关键字,相比 assign 有什么不同?

调用对象的release 方法会销毁对象吗?

    不会,调用对象的release 方法只是将对象的引用计数器-1,当对象的引用计数器为0的时候会调用了对象的dealloc 方法才能进行释放对象的内存。

自动释放池常见面试代码

for (int i = 0; i < someLargeNumber; ++i)
{   
    NSString *string = @"Abc";
    string = [string lowercaseString];
    string = [string stringByAppendingString:@"xyz"]; 
    NSLog(@"%@",string);
}

问:以上代码存在什么样的问题?如果循环的次数非常大时,应该如何修改?

存在问题:问题处在每执行一次循环,就会有一个string加到当前runloop中的自动释放池中,只有当自动释放池被release的时候,自动释放池中的标示了autorelease的这些数据所占用的内存空间才能被释放掉。假设,当someLargeNumber大到一定程度时,内存空间将被耗尽而没有被释放掉,所以就出现了内存溢出的现象。

解决办法1:如果i比较大,可以用@autoreleasepool {}解决,放在for循环外,循环结束后,销毁创建的对象,解决占据栈区内存的问题

解决方法2:如果i玩命大,一次循环都会造成自动释放池被填满,自动释放池放在for循环内,每次循环都将上一次创建的对象release
修改之后:
for(int i = 0; i<1000;i++){
NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init]; 
NSString *string = @"Abc";
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"]; 
NSLog(@"%@",string);
//释放池
[pool1 drain]; }

objective-C对象的内存布局是怎样的?

看下面的程序,第一个NSLog会输出什么?这时str的retainCount是多少?第二个和第三个呢? 为什么?

NSMutableArray* ary = [[NSMutableArray array] retain];
NSString *str = [NSString stringWithFormat:@"test"];
[str retain];
[aryaddObject:str];
NSLog(@”%@%d”,str,[str retainCount]);
[str retain];
[str release];
[str release];
NSLog(@”%@%d”,str,[str retainCount]);
[aryremoveAllObjects]
NSLog(@”%@%d”,str,[str retainCount]);
str的retainCount创建+1,retain+1,加入数组自动+1 3
retain+1,release-1,release-1 2
数组删除所有对象,所有数组内的对象自动-1 1

回答person的retainCount值,并解释为什么

Person * per = [[Person alloc] init]; 此时person 的retainCount的值是1 self.person = per;
在self.person 时,如果是assign,person的 retainCount的值不变,仍为1 若是:retain person的retainCount的值加1,变为2
若是:copy person的retainCount值不变,仍为1

什么时候需要在程序中创建内存池?

如果我们不创建内存池,是否有内存池提供给我们?

苹果是如何实现autoreleasepool的?

autoreleasepool以一个队列数组的形式实现,主要通过下列三个函数完成.
•   objc_autoreleasepoolPush
•   objc_autoreleasepoolPop
•   objc_autorelease
看函数名就可以知道,对autorelease分别执行push、pop操作。销毁对象时执行release操作。

objc使用什么机制管理对象内存?

为什么要进行内存管理?

内存管理的范围?

objc使用什么机制管理对象内存(或者内存管理方式有哪些)?(重点)

iOS是如何管理内存的?

内存管理的原则

内存管理研究的对象:

如何判断对象已经被销毁

retainCount = 0,使用retain能否复活对象

对象与对象之间存在的关系

  1. 继承关系
  2. 组合关系(是一种强烈的包含关系)
  3. 依赖关系(对象作为方法参数传递)

对象的组合关系中,确保成员变量不被提前释放?

成员变量的对象,在哪里配对释放?

对象组合关系中,内存泄露有哪几种情况?

正确重写set方法

分别描述内存管理要点、autorelease、release、NSAutoreleasePool?并说明autorelease是什么时候被release的?简述什么时候由你负责释放对象,什么时候不由你释放?[NSAutoreleasePool release]和[NSAutoreleasePool drain]有什么区别?

自动释放池是什么,如何工作 ?

自动释放池什么时候释放?

IPhone OS有没有垃圾回收?autorelease 和垃圾回收制(gc)有什么关系?

ARC问题

  1. 什么是arc机制:自动引用计数.
  2. 系统判断对象是否销毁的依据:指向对象的强指针是否被销毁
  3. arc的本质:对retainCount计算,创建+1 清空指针 - 1 或者到达autoreleasepool的大括号-1
  4. arc目的:不需要程序员关心retain和release操作.
  5. 如何解决arc机制下类的相互引用:.h文件中使用@class关键字声明一个类,两端不能都用强指针,一端用strong一端用weak

ARC通过什么方式帮助开发者管理内存?

ARC相对于MRC,不是在编译时添加retain/release/autorelease这么简单。应该是编译期和运行期两部分共同帮助开发者管理内存。

开发项目时你是怎么检查内存泄露

如果在block中多次使用 weakSelf的话,可以在block中先使用strongSelf,防止block执行时weakSelf被意外释放
对于非ARC,将 __weak 改用为 __block 即可

麻烦你设计个简单的图片内存缓存器(移除策略是一定要说的)

常见的出现内存循环引用的场景有哪些?

对象添加到通知中心中,当通知中心发通知时,这个对象却已经被释放了,可能会出现什么问题?

ARC下不显式指定任何属性关键字时,默认的关键字都有哪些?

写一个便利构造器

+(id)Person {
Person *person=[Person alloc]init];
return [person autorelease]; 备注:ARC时不用 autorelease
}

写出下面程序段的输出结果

NSDictionary *dict = [NSDictionary dictionaryWithObject:@"a string value" forKey:@"akey"]; NSLog(@"%@", [dict objectForKey:@"akey"]);
[dict release];
打印输出 a string value,然后崩溃----原因:便利构造器创建的对象,之后的release,会造成过度释放

请写出以下代码的执行结果

NSString * name = [ [ NSString alloc] init ];
name = @”Habb”;
[ name release];
打印输出结果是: Habb,在[name release]前后打印均有输出结果 ---会造成内存泄露---原先指向的区域变成了野指针,之后的释放,不能释放之前创建的区域

写出方法获取ios内存使用情况?

iOS是如何管理内存的?

我相信很多人的回答是内存管理的黄金法则,其实如果我是面试官,我想要的答案不是这样的。我希望的回答是工作中如何处理内存管理的。
参考答案:

很多内置的类,如tableview的delegate的属性是assign不是retain?

文章如有问题,请留言,我将及时更正。

满地打滚卖萌求赞,如果本文帮助到你,轻点下方的红心,给作者君增加更新的动力。

上一篇下一篇

猜你喜欢

热点阅读