5IOS面试题内存管理.docx
《5IOS面试题内存管理.docx》由会员分享,可在线阅读,更多相关《5IOS面试题内存管理.docx(8页珍藏版)》请在冰点文库上搜索。
![5IOS面试题内存管理.docx](https://file1.bingdoc.com/fileroot1/2023-6/26/1552a074-1b18-4ed9-aa07-b78926754120/1552a074-1b18-4ed9-aa07-b789267541201.gif)
5IOS面试题内存管理
1.属性readwrite,readonly,assign,retain,copy,nonatomic,atomic各是什么作用,在那种情况下用?
readwrite是可读可写特性;需要生成getter方法和setter方法时使用
readonly是只读特性 只会生成getter方法不会生成setter方法 ;不希望属性在类外改变
assign是赋值特性,不涉及引用计数,弱引用,setter方法将传入参数赋值给实例变量;仅设置变量时;
retain表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;
copy表示拷贝特性,setter方法将传入对象复制一份;需要完全一份新的变量时。
nonatomic非原子操作,不加同步,多线程访问可提高性能,但是线程不安全的。
决定编译器生成的settergetter是否是原子操作。
atomic原子操作,同步的,表示多线程安全,与nonatomic相反
2.Differencebetweenshallowcopyanddeepcopy?
浅复制和深复制的区别?
浅层复制:
只复制指向对象的指针,而不复制引用对象本身。
深层复制:
复制引用对象本身。
意思就是说我有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是一个指针,对象本身资源。
对于深复制来说,A和A_copy指向的是两个不同的内存资源,他们是两份独立对象本身。
用网上一哥们通俗的话将就是:
浅复制好比你和你的影子,你完蛋,你的影子也完蛋
深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。
3.什么是栈内存(stack)?
什么是堆内存(heap)?
栈内存:
由编译器自动分配释放,存放函数的参数值,局部变量的值等。
其操作方式类似于数据结构中的栈(先进后出)。
在内存中占连续的空间,紧密依次排列,效率很高,要优于堆内存,但是分配容量有限。
在IOS开发中,栈内存里主要存放的是任何C类型,如int、short、char、long、struct、enum等基本数据类型或者结构体。
堆内存:
也叫散列堆,在运行的过程中动态内存分配。
需要在创建对象的时候通过alloc开辟空间,不用的时候需要release释放,因为开辟的空间的时候不不是完全连续的,所以会出现内存碎片,需要我们管理。
此外,如果我们动态的申请了内存,使用结束后没有释放,就会发生内存泄露。
堆内存主要存储继承自NSObject类的所有OC对象。
4.IOS开发内存管理的对象有哪些?
不管理的有哪些?
内存管理的对象为继承自NSObject类的所有OC对象,也就是存在堆内存中的数据,也叫引用类型。
不需要管理的对象为任何C类型,如int、short、char、long、struct、enum等基本数据类型或者结构体,它们存放在栈内存中,也叫值类型。
OC主要管理的是堆内存,栈内存自动管理。
5.什么是引用类型?
什么是值类型?
它们之间可以相互转化么?
引用类型就是继承NSObject类的类型。
值类型就是C中基本数据类型。
引用类型和值类型之间可以进行相互的转化,比如NSNumber与int,两者就可以转化:
NSNumber*number=[NSNumbernumberWithInt:
1];
intnum=[numberintValue];
6.什么是装箱(boxing)?
什么是拆箱(unboxing)?
把值类型转为引用类型,叫装箱,也叫向上转型。
把引用类型转为值类型,叫拆箱,也叫向下转型。
7.装箱和拆箱会造成什么问题?
装箱,向上转型,会造成性能损失。
拆箱,向下转型,会造成安全性问题。
8.Objective-C如何对内存管理的,说说你的看法和解决方法?
内存管理,就是对内存资源进行优化。
Objective-C的内存管理主要有三种方式ARC(自动内存计数)、MRC(手动内存计数)、内存池。
ARC现在用的比较广泛,它可以简化我们的代码,不用担心内存泄露。
(补充解释三种方式,参见后面题目)
9.MRC是什么?
它的管理原则是什么?
管理不好会出现什么问题?
MRC,全称MannulReferenceCounting,手动内存管理(手动引用计数),需要程序员手动的创建对象申请内存,然后再手动的释放。
MRC管理内存的原则:
谁创建,谁释放。
也就是说,在使用的过程中,谁retain,谁release;或者谁alloc,谁release。
在使用MRC时,当引用计数为0时,必须回收,引用计数不为0,则不回收;如果内存计数为0了,没回收,会造成内存泄露。
如果想使用已经创建好的某个对象(别人创建的),不能直接拿过去用,需要先retain(让计数+1),用完之后应该release(计数-1),否则会造成野指针。
10.什么是野指针?
如何避免野指针?
野指针(不知道指向哪里的指针),它指向了一块不属于它的内存,可能是别人的内存,也可能之前是自己的,但是被别人释放了。
避免野指针的方式就是释放之后,让指针等于nil,这个时候在重复释放,则不会提示错误。
nil:
又名空,是操作系统持有的内存,任何人都夺不去的内存。
11.如何解决AreatainB,BreatainA,相互持有的问题?
一方用retain,一方用weak。
12.ARC是什么?
ARC是iOS5推出的新功能,全称叫AutomaticReferenceCounting,自动引用计数。
简单地说,就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。
使用ARC,只要某个对象被任一strong指针指向,那么它将不会被销毁。
如果对象没有被任何strong指针指向,那么就将被销毁。
使用ARC后,不允许调用release,retain、retainCount等方法。
允许重写dealloc,但是不允许调用[superdealloc],系统会默认调用[superdealloc]。
13.谈谈ARC与MRC各自优缺点?
ARC优点是使用起来比较简单,不用自己考虑内存问题等,在MRC时代你需要自己retain一个想要保持的对象,而现在不需要了。
现在唯一要做的是用一个指针指向这个对象,只要指针没有被置空,对象就会一直保持在堆上。
当将指针指向新值时,原来的对象会被release一次。
ARC缺点是如果出现循环引用的时候,容易出现内存泄露。
此外,许多第三方的库是用MRC写的,如果使用,需要做一定处理。
MRC优点是程序员对于内存的控制比较强,可以很好的解决内存问题。
MRC缺点是需要手动的写大量代码管理内存,保证谁创建谁释放,避免空指针,要很仔细才可以。
14.ARC与MRC两者可以混着一起用么?
可以。
ARC中使用MRC:
在targets的buildphases选项下CompileSources下选择要不使用arc编译的文件,双击它,输入-fno-objc-arc即可.
MRC中使用ARC:
在targets的buildphases选项下CompileSources下选择要使用arc编译的文件,双击它,输入-fobjc-arc即可。
15.IsthereanygarbagecollectionmechanisminObjectiveC.?
OC的垃圾回收机制?
OC2.0有Garbagecollection,但是iOS平台不提供,只针对mac应用程序开发。
注意要与MRC、ARC区分开。
16.什么是引用计数(RetainCount)?
判断对象是否被回收的标志,如果为0回收,不为0不回收。
每个OC对象都有自己的引用计数器,它是一个整数,表示对象被引用的数量。
每个OC对象内部专门有4个字节的存储空间来存储引用计数器。
17.内存管理的几个关键字分别是什么?
引用计数在什么时候+1减-1?
关键字有:
alloc分配内存、release释放、retain
对象new或者alloc(分配内存)时+1;
对象发送retain时+1;
对象release(释放)时-1.
ARC模式下不需要自己管理引用计数。
MRC模式下需要自己管理引用计数:
当引用计数为0,对象被销毁;销毁时调用dealloc方法。
如果要重写dealloc,必须调用[superdealloc],并且必须写到最后一句。
如果调用了dealloc,对象将被回收,内存不可以使用,再次使用会crash(闪退)。
18.autorelease是什么意思?
优势?
缺点?
autorelease类似于release,但是不等同于它,release调用后引用计数马上-1。
autorelease是在创建对象的时候写的,表示加入自动释放池,当释放池销毁时,才调用引用计数-1。
优点:
可以简化操作,由自动释放池管理。
只有在自动释放池销毁时才对里面的对象进行销毁,程序员不用关心对象的销毁时间,也不用再去调用release。
缺点:
因为是延迟释放,可以延长对象的生命周期。
所以不要随意使用,因为对象生命周期延长,会一直持有内存,会减慢速度。
适合占内存小的对象使用。
19.autoreleasepool是什么?
自动释放池,需要手动创建。
当调用[pooldrain]方法时,会调用池中得全部对象,release掉他们。
20.ARC中两种引用方式?
strong:
强引用(指向它自己,不管别人)
与retain类似,使用之后,计数器+1。
weak:
弱引用(依附于别人,别人在,它在,别人不在,他也不在,计数永远为1)
如果指向的对象被释放了,其指向nil,可以有效的避免野指针。
21.内存管理的几条原则是什么?
按照默认法则.那些关键字生成的对象需要手动释放?
在和property结合的时候怎样有效的避免内存泄露?
谁申请,谁释放
遵循CocoaTouch的使用原则;
内存管理主要要避免“过早释放”和“内存泄漏”。
对于“过早释放”需要注意@property设置特性时,一定要用对特性关键字;对于“内存泄漏”,一定要申请了要负责释放,要细心。
如果使用MRC,关键字alloc或new生成的对象需要手动释放;设置正确的property属性,对于retain需要在合适的地方释放.
ARC是不需要手动释放的。
22.看下面的程序,第一个NSLog会输出什么?
这时str的retainCount是多少?
第二个和第三个呢?
为什么?
NSMutableArray*ary=[[NSMutableArrayarray]retain];
NSString*str=[NSStringstringWithFormat:
@"test"];
[strretain];
[aryaddObject:
str];
NSLog(@"First:
%@%i",str,[strretainCount]);
[strretain];
[strrelease];
[strrelease];
NSLog(@"%@%i",str,[strretainCount]);
[aryremoveAllObjects];
NSLog(@"%@%i",str,[strretainCount]);
答案:
First:
test3
str的retainCount创建+1,retain+1,加入数组自动+1
Secound:
test2
retain+1,release-1,release-1
Third:
test1
数组删除所有对象,所有数组内的对象自动-1
23.如何对iOS设备进行性能测试?
Profile->Instruments->TimeProfiler
24.写一个setter方法用于完成
@property(nonatomic,retain)NSString*name;
-(void)setName:
(NSString*)str
{
[strretain];
[namerelease];
name=str;
}
写一个setter方法用于完成
@property(nonatomic,copy)NSString*name;
-(void)setName:
(NSString*)str
{
idt=[strcopy];
[namerelease];
name=t;
}