关于最近遇到的一些iOS面试题<2>答案来自网络

来源:互联网 发布:大嘴猴天鹅绒知乎 编辑:程序博客网 时间:2024/05/21 10:55

1、请写出UIViewController的完整生命周期

参考答案:

下面是笔者通过打印,先出现ViewController,然后在点击ViewController上的按钮时,模态弹出了一个纯代码HYBViewController,其打印如下:

-[ViewController initWithCoder:]-[ViewController loadView]-[ViewController viewDidLoad]-[ViewController viewWillAppear:]-[ViewController viewDidAppear:]// present HYBViewController-[HYBViewController initWithNibName:bundle:]-[HYBViewController init]-[HYBViewController loadView]-[HYBViewController viewDidLoad]-[ViewController viewWillDisappear:]-[HYBViewController viewWillAppear:]-[HYBViewController viewDidAppear:]-[ViewController viewDidDisappear:]

生命周期如下:

  • xib/storyboard:-initWithCoder:,而非xib/storyboard的是-initWithNibName:bundle:然后-init
  • -loadView
  • -viewDidLoad
  • -viewWillAppear:
  • -viewDidAppear:
  • -viewWillDisappear:
  • -viewDidDisappear:

注意,当从ViewController进入到HYBViewController控制器时,注意出现顺序如下:

  • -[ViewController viewWillDisappear:]
  • -[HYBViewController viewWillAppear:]
  • -[HYBViewController viewDidAppear:]
  • -[ViewController viewDidDisappear:]

在HYBViewController完全出现后,才会调用前一个控制器的完全消失。像这种要不同控制器之间导航条隐藏与显示控制问题,就需要特别注意其生命周期的顺序。

2.请写出有多少有方法给UIImageView添加圆角?

参考答案:

  1. 最直接的方法就是使用如下属性设置:
imgView.layer.cornerRadius = 10;// 这一行代码是很消耗性能的imgView.clipsToBounds = YES;

好处是使用简单,操作方便。坏处是离屏渲染(off-screen-rendering)需要消耗性能。对于图片比较多的视图上,不建议使用这种方法来设置圆角。通常来说,计算机系统中CPU、GPU、显示器是协同工作的。CPU计算好显示内容提交到GPU,GPU渲染完成后将渲染结果放入帧缓冲区。

简单来说,离屏渲染,导致本该GPU干的活,结果交给了CPU来干,而CPU又不擅长GPU干的活,于是拖慢了UI层的FPS(数据帧率),并且离屏需要创建新的缓冲区和上下文切换,因此消耗较大的性能。

  1. 给UIImage添加生成圆角图片的扩展API:
- (UIImage *)hyb_imageWithCornerRadius:(CGFloat)radius {  CGRect rect = (CGRect){0.f, 0.f, self.size};  UIGraphicsBeginImageContextWithOptions(self.size, NO, UIScreen.mainScreen.scale);  CGContextAddPath(UIGraphicsGetCurrentContext(),                   [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath);  CGContextClip(UIGraphicsGetCurrentContext());  [self drawInRect:rect];  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();  UIGraphicsEndImageContext();  return image;}

然后调用时就直接传一个圆角来处理:

imgView.image = [[UIImage imageNamed:@"test"] hyb_imageWithCornerRadius:4];

这么做就是on-screen-rendering了,通过模拟器->debug->Color Off-screen-rendering看到没有离屏渲染了!(黄色的小圆角没有显示了,说明这个不是离屏渲染了)

  1. 在画之前先通过UIBezierPath添加裁剪,但是这种不实用:
- (void)drawRect:(CGRect)rect {  CGRect bounds = self.bounds;  [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:8.0] addClip];  [self.image drawInRect:bounds];}

3、请描述事件响应者链的工作原理

参考答案:

iOS使用hit-testing寻找触摸的view。 Hit-Testing通过检查触摸点是否在关联的view边界内,如果在,则递归地检查该view的所有子view。在层级上处于lowest(就是离用户最近的view)且边界范围包含触摸点的view成为hit-test view。确定hit-test view后,它传递触摸事件给该view。

官方小例子事件响应者链如下图所示:

  • 触摸点在view A中,所以要先检查子view B和C。
  • 触摸点不在view B中,但在C中,所以检查C的子view D和E。
  • 触摸点不在D中,但在E中。View E是这个层级上处于lowest的view的边界范围包含触摸点,所以它成为了hit-test view。

Hit-test view是处理触摸事件的第一选择,如果hit-test view不能处理事件,该事件将从事件响应链中寻找响应器,直到系统找到一个处理事件的对象。若不能处理,则就有事件传递链了,继续看下面的事件传递链。

事件传递链如下图所示:

左半图:

  • initial view若不能处理事件,则传到其父视图view
  • view若不能处理,则传到其父视图,因为它还不是最上层视图
  • 这里view的父视图是view controller的view,因为这个view也不能处理事件,因此传给view controller
  • 若view controller也不能处理此事件,则传到window
  • 若window也不能处理此事件,则传到app单例对象Application
  • 若UIApplication单例对象也不能处理,则表示无效事件

右半图:

  • initial view一直传递直到最上层view(原话:A view passes an event up its view controller’s view hierarchy until it reaches the topmost view.)
  • topmost view传递事件到它所在的控制器(原话:The topmost view passes the event to its view controller.)
  • view controller传递事件到topmost view的父视图,重复前三步,走到到达root controller(原话:passes the event to its topmost view’s superview.
    Steps 1-3 repeat until the event reaches the root view controller.)

  • 由root控制器传递事件到window(原话:The root view controller passes the event to the window object.)

  • 若window也不能处理此事件,则传到app单例对象Application
  • 若UIApplication单例对象也不能处理,则表示无效事件

为了解答这个小题目,翻阅了官方文档,由于内容较多,这里不说那么多,若要了解更多,参考官方文档吧:Event Handling Guide for iOS


4、请比较GCD与NSOperation的异同

参考答案:

  • 相同点:GCD和NSOperation都是苹果提供的多线程实现方案。
  • 不同点:GCD是轻量级的纯C写的多线程实现方案,使用起来非常方便,在开发中大量使用,但是对于取消和暂停线程就比较麻烦些。而NSOperation是面向对象的,兼容KVO,对于取消和暂停任务是非常容易的。


0 0
原创粉丝点击