iOS程序员面试题系列(3)

来源:互联网 发布:linux home目录不见了 编辑:程序博客网 时间:2024/06/08 10:07

1.UIWindow和UIView和CALayer的联系和区别?

答:UIView是视图的基类,UIViewController是视图控制器的基类,UIResponder是表示一个可以在屏幕上响应触摸事件的对象;

UIWindow是UIView的子类,UIWindow的主要作用:一是提供一个区域来显示UIView,二是将事件(event)的分发给UIView,一个应用基本上只有一个UIWindow。

万物归根,UIView和CALayer的老祖都是NSObject。可见UIResponder是用来响应事件的,也就是UIView可以响应用户事件。

CALayer和UIView的区别:

1.1UIView的继承结构为:UIResponder:NSObject。

  CALayer的继承结构为:NSObject。可见UIResponder是用来响应事件的,也就是UIView可以响应用户事件.

  CALayer直接从NSObject继承,因为缺少了UIResponder类,不能响应任何用户事件。

1.2所属框架,UIView是在/System/Library/Frameworks/UIKit.framework中定义的,UIKit主要是用来构建用户界面,并且是可以响应事件的;CALayer是在/System/Library/Frameworks/QuartzCore.framework中定义的。而且CALayer作为一个低级的,可以承载绘制内容的底层对象出现在该框架中。

1.3UIView相比CALayer最大的区别是UIView可以响应用户事件,而CALayer不可以。UIView侧重于对显示内容的管理,CALayer侧重于对内容的绘制。UIView是基于CALayer的高层封装。

1.4相似支持(1):相似的树形结构(2):显示内容绘制方式(3):布局约束

总结一下就是:UIView是用来显示内容的,可以处理用户事件,CALayer是用来绘制内容的,对内容进行动画处理依赖于UIView来进行显示,不能处理用户事件。

为啥有两套体系,并不是两套体系?

UIView和CALayer是相互依赖的关系。UIView依赖于CALayer提供的内容,CALayer依赖UIView提供的容器来显示绘制的内容,归根到底CALayer是这一切的基础,如果没有CALayer,UIView自身也不会存在,UIView是一个特殊的CALayer实现,添加了响应事件的能力。UIView本身,更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性,例如frame,bounds等等,实际上内部都是在访问它所包含的CALayer的相关属性。


UIView的layer树形在系统内部,被系统维护着三份copy。

第一份:逻辑树,就是代码里可以操纵的,例如更改layer的属性等等就在这一份。

第二份:动画树,这是一个中间层,系统正在这一层上更改属性,进行各种渲染操作。

第三份:显示树:这棵树的内容是当前正被显示在屏幕上的内容。

这三棵树的逻辑结构都是一样的,区别只有各自的属性。


UIView的主layer以外,对它的subLayer,也就是子layer的属性进行更改,系统将自动进行动画生成。

CALayer的坐标系系统和UIView有点不一样,它多了一个叫anchorPoint的属性,它使用CGPoint结构,但是值域是0~1,也就是按照比例来设置。这个点是各种图形变换的坐标原点,同时会更改layer的position的位置,它的缺省值是{0.5,0.5},也就是在layer的中央。

参考链接:

http://o0o0o0o.iteye.com/blog/1728599

http://www.cnblogs.com/pengyingh/articles/2381673.html

2.property都有哪些常用的字段?

答:strong, weak, retain, assign, copy, nomatic, readonly。


3.strong, weak, retain,assign, copy, nonatomic等的区别?

答:assign:简单赋值,对基础数据类不更改索引计数(Reference Counting);

Copy:建立一个索引计数为1的对象,然后释放旧对象,对于NSString。

Retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1,对于其他的NSObject和其子类。

Weak和strong的区别:weak和strong不同的是,当一个对象不再有strong类型的指针指向它的时候,它会被释放,即使还有weak型指针指向它。一旦最后一个strong型指针离去,这个对象将被释放,所有剩余的weak型指针都将被清除。

Copy与retain的区别:

Copy其实是建立了一个相同的对象,而retain不是;

Copy是内容拷贝,retain是指针拷贝;

Copy是内容的拷贝,对于像NSString,的确是这样,如果拷贝的是NSArray,这时只是copy了指向array中相对应元素的指针,这便是所谓的“浅复制”。


Atomic是Objective-C使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。

对于NSString为什么使用copy参考这篇链接:

http://southpeak.github.io/blog/2015/05/10/ioszhi-shi-xiao-ji-di-%5B%3F%5D-qi-2015-dot-05-dot-10/


4._block和_weak修饰符的区别:

答:_block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。

_weak只能在ARC模式下使用,也职能修饰对象(NSString),不能修饰基本数据类型(int)。

_block对象可以在block中被重新赋值,_weak不可以。


5.常见的Http状态码有哪些?

答:http状态码:302是请求重定向,500以上是服务器错误。400以上是请求链接错误或者找不到服务器。200以上是正确的。100以上是请求接受成功。

参考链接:http://zhangmingwei.iteye.com/blog/1748431


6.单例的写法,在单例中使用数组要注意什么?

答:static PGSingleton *sharedSingleton;

+(instancetype)sharedSingleton

{

     Static dispatch_once_t onceToken;

     Dispatch_once(&onceToken,^{

        sharedSingleton = [[PGSingletonalloc]init];

     });

     Return sharedSingleton;

}

其实上面的还不是标准的单例写法,标准的单例写法需要重写copyWithZone,allocWithZone,init,确保以任何方式创建出来的对象只有一个。


单例使用NSMutableArray的时候,防止多个地方对它同时遍历和修改的话,需要加原子属性。并且property用strong,并且写一个遍历和修改的方法。加上锁.Lock,.UnLock(PS:考虑性能问题尽量避免使用锁。)


关于单例的参考,和不要滥用单例的参考:

http://www.jianshu.com/p/7486ebfcd93b

http://blog.codingcoder.com/singletons/


7.static关键字的作用

答:1>.函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;

2>.在模块内的static全局变量可以被模块内的所有函数访问,但不能被模块外其他函数访问;

3>.在模块内的static函数只可被这一模块内的其他函数调用,这个函数的使用范围被限制在声明它的模块内;

4>.在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝。

5>.在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。


8.iOS中的事件的传递:响应链

答:事件沿着一个指定的路径传递直到它遇见可以处理它的对象,首先一个UIApplication对象从队列顶部获取一个事件并分发(dispatches)它以便处理。通常,它把事件传递给应用程序的关键窗口对象,该对象把事件传递给一个初始对象来处理。初始对象取决于事件的类型。

触摸时间:对于触摸事件,窗口对象首先尝试把事件传递给触摸发生的视图,那个视图被称为hit-test(点击测试)视图。寻找hit-test视图的过程被称为hit-testing.

运动和远程控制事件。对于这些事件,窗口对象把shaking-motion(摇晃运动)或远程控制事件传递给第一响应者来处理。


iOS使用hit-testing来找到事件发生的视图。Hit-testing包括检查触摸事件是否发生在任何相关视图对象的范围内,如果是,则递归地检查所有视图的子视图。在视图层次中的最底层视图,如果它包含了触摸点,那么它就是hit-test视图。等iOS决定了hit-test视图之后,它把触摸事件传递给该视图以便处理。

http://yishuiliunian.gitbooks.io/implementate-tableview-to-understand-ios/content/uikit/132event-chains.html


9.堆和栈的区别:

管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作是由程序员控制,容易产生memory leak。

申请大小

栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在Windows下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。

堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低;对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出。

分配方式:堆都是动态分配的,没有静态分配的堆。栈有两种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloc函数进行分配,但是栈的动态分配和堆是不同的,它的动态分配是由编译器进行释放,无需我们手工实现。

分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。

0 0
原创粉丝点击