iOS面试题汇总整理.docx
《iOS面试题汇总整理.docx》由会员分享,可在线阅读,更多相关《iOS面试题汇总整理.docx(12页珍藏版)》请在冰豆网上搜索。
iOS面试题汇总整理
1.Differencebetweenshallowcopyanddeepcopy?
浅复制和深复制的区别?
答:
浅复制是指复制对象的指针,不复制对象本身。
深复制是指复制引用对象本身。
意思就是说我有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是一个指针,对象本身资源还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。
深复制就好理解了,内存中存在了两份独立对象本身。
2.Whatisadvantageofcategories?
Whatisdifferencebetweenimplementingacategoryandinheritance?
类别的作用?
继承和类别在实现中有何区别?
答:
categories是可以在不知道,不改变原来代码的情况下,往里面添加新的方法。
只能添加,不能删除和修改。
并且,如果类别和原来类中的方法名冲突,则类别将覆盖原方法,因为类别具有更高的优先级。
类别主要有3个作用:
(1):
将类的实现分散到多个不同文件或者多个不同框架中。
(2):
创建对私有方法的前向引用。
(3):
向对象添加非正式协议。
继承可以添加,修改方法,并且可以增加属性。
3.Differencebetweencategoriesandextensions?
类别和类扩展(延展)的区别?
答:
相同点:
都可以添加属性和方法。
不同点:
延展可以合成属性,可以添加实例变量。
4.Object-c的类可以多重继承么?
可以实现多个接口么?
Category是什么?
重写一个类的方式用继承好还是分类好?
为什么?
答:
OC中的类不可以多重继承,可以用protocol委托代理来完成多继承。
可以实现多个接口。
Category是类别。
一般情况下重写一个方法用分类比较好,用Category重写类的方法,仅对本category有效,不会影响到其他类与原有类的关系。
5.#import跟#include又什么区别,@class呢,#import<>跟#import”"又什么区别?
答:
#import是Object——C导入头文件的关键字,#include是C和C++导入头文件的关键字。
使用import头文件会自动只导入一次,不会重复导入,不会产生重复编译。
@class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含。
#import<>用来引入类库或者框架的头文件,#import““用来引入非类库的头文件。
6.属性readwrite,readonly,assign,retain,copy,nonatomic各是什么作用,在那种情况下用?
答:
readwrite:
是可读可写特性,在需要生成getter和setter方法时用。
readonly:
是只读特性,只会生成getter方法,不会生成setter方法,不希望属性在类外改变。
Assign:
是赋值特性,setter方法将传入参数赋值给实例变量。
仅在设置变量时用。
Retain:
表示持有特性,setter方法将传入参数先保留再赋值,传入参数的retaincount会加1。
Copy:
表示赋值特性,setter方法将传入对象复制一份。
在需要完全一份新的变量时候使用。
Nonatomic:
非原子操作,决定编译器生成的getter和setter是否是原子操作。
Atomic:
表示多线程安全,一般使用nonatomic。
7.内存管理的几条原则时什么?
按照默认法则.那些关键字生成的对象需要手动释放?
在和property结合的时候怎样有效的避免内存泄露?
答:
原则:
1如果使用alloc或者copy方法创建的对象,或者使用retain保留一个对象,那么都要自己释放对象。
(即:
谁申请,谁释放)
2:
在大多数情况下,申请内存的语句数量和释放内存的语句数量应该相等。
3:
尽量少使用内存,用完后立即释放。
关键字:
create,copy,alloc和new生成的对象需要手动释放。
设置正确的property属性,对于retain需要在合适的地方释放,可以有效避免内存泄漏。
8.Whatispurposeofdelegates?
代理的作用?
答:
代理的目的是改变或传递控制链。
允许一个类在某些特定时刻通知到其他类,而不需要获取
到那些类的指针。
可以减少框架的复杂度。
9:
static关键字的作用?
答:
(1):
在函数体内,static变量的作用局限为该函数体,该变量的内存只被分配一次。
因此其值在下次调用时仍维持上次的值。
(2):
在模块内,static全局变量可以被模块内所用函数访问,但不能被模块外的其他函数访问。
(3):
在模块内的static函数只可被这一模块内的其他函数调用,这个函数的使用局限被限制在声明他的模块内。
(4):
在类中的static成员变量属于整个类所拥有,对类的所有对象唯有一份copy。
(5):
在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
10:
关键字const什么含义
const意味着”只读”,
下面的声明都是什么意思?
constinta;
intconsta;
constint*a;
int*consta;
intconst*aconst;
前两个的作用是一样,a是一个常整型数。
第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。
第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。
最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。
结论:
•;关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。
如果
你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。
(当然,懂得用const的程序员很少会留下的垃圾让别人来清
理的。
)
•;通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。
•;合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。
简而言之,这样可以减少bug的出现。
欲阻止一个变量被改变,可以使用const关键字。
在定义该const变量时,通常需要对它进行初
始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指
定为const;
(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。
11:
关键字volatile有什么含义?
并给出三个不同例子?
答:
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。
精确地说就是,优化器在用到
这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
下面是volatile变量的几个例子:
•并行设备的硬件寄存器(如:
状态寄存器)
•一个中断服务子程序中会访问到的非自动变量(Non-automaticvariables)
•多线程应用中被几个任务共享的变量
12•一个参数既可以是const还可以是volatile吗?
解释为什么。
答:
是的。
一个例子是只读的状态寄存器。
它是volatile因为它可能被意想不到地改变。
它是const因为程序不应该试图去修改它。
13•一个指针可以是volatile吗?
解释为什么。
答:
是的。
尽管这并不很常见。
一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
14:
线程和进程的区别?
进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。
进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。
线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。
但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
15:
堆和栈的区别?
管理方式:
对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memoryleak。
申请大小:
栈:
在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。
这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。
因此,能从栈获得的空间较小。
堆:
堆是向高地址扩展的数据结构,是不连续的内存区域。
这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。
堆的大小受限于计算机系统中有效的虚拟内存。
由此可见,堆获得的空间比较灵活,也比较大。
碎片问题:
对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。
对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出
分配方式:
堆都是动态分配的,没有静态分配的堆。
栈有2种分配方式:
静态分配和动态分配。
静态分配是编译器完成的,比如局部变量的分配。
动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。
分配效率:
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:
分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。
堆则是C/C++函数库提供的,它的机制是很复杂的。
16:
Object-C的内存管理?
1.当你使用new,alloc和copy方法创建一个对象时,该对象的保留计数器值为1.当你不再使用该对象时,你要负责向该对象发送一条release或autorelease消息.这样,该对象将在使用寿命结束时被销毁.
2.当你通过任何其他方法获得一个对象时,则假设该对象的保留计数器值为1,而且已经被设置为自动释放,你不需要执行任何操作来确保该对象被清理.如果你打算在一段时间内拥有该对象,则需要保留它并确保在操作完成时释放它.
3.如果你保留了某个对象,你需要(最终)释放或自动释放该对象.必须保持retain方法和release方法的使用次数相等.
17:
对象是什么时候被dealloc的?
引用计数为0时。
autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autoreleasepool中,当该pool被释放时,该pool中的所有Object会被调用Release。
对于每一个Runloop,系统会隐式创建一个Autoreleasepool,这样所有的releasepool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autoreleasepool会被销毁,这样这个pool里的每个Object(就是autorelease的对象)会被release。
那什么是一个Runloop呢?
一个UI事件,Timercall,delegatecall,都会是一个新的Runloop
18:
iOS有没有垃圾回收?
Objective-C2.0也是有垃圾回收机制的,但是只能在MacOSXLeopard10.5以上的版本使用。
19:
怎么理解MVC,在Cocoa中MVC是怎么实现的?
MVC设计模式考虑三种对象:
模型对象、视图对象、和控制器对象。
模型对象代表特别的知识和专业技能,它们负责保有应用程序的数据和定义操作数据的逻辑。
视图对象知道如何显示应用程序的模型数据,而且可能允许用户对其进行编辑。
控制器对象是应用程序的视图对象和模型对象之间的协调者。
20:
id、nil代表什么?
id和void*并非完全一样。
在上面的代码中,id是指向structobjc_object的一个指针,这个意思基本上是说,id是一个指向任何一个继承了Object(或者NSObject)类的对象。
需要注意的是id是一个指针,所以你在使用id的时候不需要加星号。
比如idfoo=nil定义了一个nil指针,这个指针指向NSObject的一个任意子类。
而id*foo=nil则定义了一个指针,这个指针指向另一个指针,被指向的这个指针指向NSObject的一个子类。
nil和C语言的NULL相同,在objc/objc.h中定义。
nil表示一个Objctive-C对象,这个对象的指针指向空(没有东西就是空)。
21:
Object-C有私有方法吗?
私有变量呢?
objective-c–类里面的方法只有两种,静态方法和实例方法.这似乎就不是完整的面向对象了,按照OO的原则就是一个对象只暴露有用的东西.如果没有了私有方法的话,对于一些小范围的代码重用就不那么顺手了.在类里面声名一个私有方法
@interfaceController:
NSObject{NSString*something;}
+(void)thisIsAStaticMethod;
–(void)thisIsAnInstanceMethod;
@end
@interfaceController(private)-
(void)thisIsAPrivateMethod;
@end
@private可以用来修饰私有变量
在Objective‐C中,所有实例变量默认都是私有的,所有实例方法默认都是公有的
22:
retaincount?
关于引用计数?
答:
1:
当通过alloc和new初始化一个对象的时候,引用计数为1.
2:
当对该对象retain或者被另外一个对象保留或持有的时候(数组),引用计数加1.
3;当用release或autorelease或其他对象取消持有时,引用计数减1.
4:
当引用计数为0时,系统会自动调用dealloc方法来释放该对象。
23:
self.跟self有什么区别?
24:
什么是KVO和KVC?
答案:
kvc:
键-值编码是一种间接访问对象的属性使用字符串来标识属性,而不是通过调用存取方法,直接或通过实例变量访问的机制。
很多情况下可以简化程序代码。
kvo:
键值观察机制,他提供了观察某一属性变化的方法,极大的简化了代码。
25:
自动释放池是什么,如何工作?
当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。
它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。
当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。
1. ojc-c是通过一种"referringcounting"(引用计数)的方式来管理内存的,对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰到有copy,retain的时候引用计数都会加一,每当碰到release和autorelease的时候引用计数就会减一,如果此对象的计数变为了0,就会被系统销毁.
2.NSAutoreleasePool就是用来做引用计数的管理工作的,这个东西一般不用你管的.
3.autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一.
26:
WhataremutableandimmutabletypesinObjectiveC?
obc中可修改和不可以修改类型。
答案:
可修改不可修改的集合类。
这个我个人简单理解就是可动态添加修改和不可动态添加修改一样。
比如NSArray和NSMutableArray。
前者在初始化后的内存控件就是固定不可变的,后者可以添加等,可以动态申请新的内存空间。
27.Differencebetweenframeandbounds?
frame和bounds有什么不同?
答案:
frame指的是:
该view在父view坐标系统中的位置和大小。
(参照点是父亲的坐标系统)
bounds指的是:
该view在本身坐标系统中的位置和大小。
(参照点是本身坐标系统)
28.Differencebetweenmethodandselector?
方法和选择器有何不同?
答案:
selector是一个方法的名字,method是一个组合体,包含了名字和实现.
29.Whatislazyloading?
答案:
懒汉模式,只在用到的时候才去初始化。
也可以理解成延时加载。
我觉得最好也最简单的一个列子就是tableView中图片的加载显示了。
一个延时载,避免内存过高,一个异步加载,避免线程堵塞。
30:
ios平台怎么做数据的持久化?
coredata和sqlite有无必然联系?
coredata是一个关系型数据库吗?
iOS中可以有四种持久化数据的方式:
属性列表、对象归档、SQLite3和CoreData;coredata可以使你以图形界面的方式快速的定义app的数据模型,同时在你的代码中容易获取到它。
coredata提供了基础结构去处理常用的功能,例如保存,恢复,撤销和重做,允许你在app中继续创建新的任务。
在使用coredata的时候,你不用安装额外的数据库系统,因为coredata使用内置的sqlite数据库。
coredata将你app的模型层放入到一组定义在内存中的数据对象。
coredata会追踪这些对象的改变,同时可以根据需要做相反的改变,例如用户执行撤销命令。
当coredata在对你app数据的改变进行保存的时候,coredata会把这些数据归档,并永久性保存。
macosx中sqlite库,它是一个轻量级功能强大的关系数据引擎,也很容易嵌入到应用程序。
可以在多个平台使用,sqlite是一个轻量级的嵌入式sql数据库编程。
与coredata框架不同的是,sqlite是使用程序式的,sql的主要的API来直接操作数据表。
CoreData不是一个关系型数据库,也不是关系型数据库管理系统(RDBMS)。
虽然CoreDta支持SQLite作为一种存储类型,但它不能使用任意的SQLite数据库。
CoreData在使用的过程种自己创建这个数据库。
CoreData支持对一、对多的关系。
31:
Whatisresponderchain?
说说响应链
答案:
事件响应链。
包括点击事件,画面刷新事件等。
在视图栈内从上至下,或者从下之上传播。
可以说点事件的分发,传递以及处理。
32:
whatisdifferencebetweenNSNotificationandprotocol?
通知和协议的不同之处?
答案:
协议有控制链(has-a)的关系,通知没有。
首先我一开始也不太明白,什么叫控制链(专业术语了~)。
但是简单分析下通知和代理的行为模式,我们大致可以有自己的理解
简单来说,通知的话,它可以一对多,一条消息可以发送给多个消息接受者。
代理按我们的理解,到不是直接说不能一对多,比如我们知道的明星经济代理人,很多时候一个经济人负责好几个明星的事务。
只是对于不同明星间,代理的事物对象都是不一样的,一一对应,不可能说明天要处理A明星要一个发布会,代理人发出处理发布会的消息后,别称B的
发布会了。
但是通知就不一样,他只关心发出通知,而不关心多少接收到感兴趣要处理。
因此控制链(has-a从英语单词大致可以看出,单一拥有和可控制的对应关系。
33.id声明的对象有什么特性?
答:
Id声明的对象具有运行时的特性,即可以指向任意类型的objcetive-c的对象;
34.Objective-C如何对内存管理的,说说你的看法和解决方法?
答:
Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。
35.whatisdifferencebetweenNSNotificationandprotocol?
通知和协议的不同之处?
答案:
协议有控制链(has-a)的关系,通知没有。
首先我一开始也不太明白,什么叫控制链(专业术语了~)。
但是简单分析下通知和代理的行为模式,我们大致可以有自己的理解
简单来说,通知的话,它可以一对多,一条消息可以发送给多个消息接受者。
代理按我们的理解,到不是直接说不能一对多,比如我们知道的明星经济代理人,很多时候一个经济人负责好几个明星的事务。
只是对于不同明星间,代理的事物对象都是不一样的,对应,不可能说明天要处理A明星要一个发布会,代理人发出处理发布会的消息后,别称B的
发布会了。
但是通知就不一样,他只关心发出通知,而不关心多少接收到感兴趣要处理。
因此控制链(has-a从英语单词大致可以看出,单一拥有和可控制的对应关系。
36.Whatispushnotification?
什么是推送消息?
答:
推送通知更是一种技术。
简单点就是客户端获取资源的一种手段。
普通情况下,都是客户端主动的pull。
推送则是服务器端主动push。
37.Polymorphism?
关于多态性
38.Singleton?
对于单例的理解
Singleton模式,也就是通常所说的单例模式,主要用做应用程序的资源共享控制。
应该说,这个模式的使用频率非常高。
通过Singleton一个Class,可以实现在不同窗口之间传递数据。
在Objective-C中,要实现一个SingletonClass,至少需要做以下四个步骤:
1. 为SingletonObject实现一个静态实例,并初始化,然后设置成nil;
2. 实现一个实例构造方法(通常命名为sharedInstance或者sharedManager)检查上面声明的静态实例是否为nil,如果是,则新建并返回一个本类实例;
3.重写allocWithZone:
方法,用来保证当其他人直接使用alloc和init试图获得一个新实例的时候,不会产生一个新的实例。
4.适当地实现 allocWithZone, copyWithZone, release和autorelease。
39.Canweusetwotableviewcontrollersononeviewcontroller?
是否在一个视图控制器中嵌入两个tableview控制器?
答案:
一个视图控制只提供了一个View视图,理论上一个tableViewController