美文网首页
iOS面试题-UI篇

iOS面试题-UI篇

作者: Peter杰 | 来源:发表于2019-10-28 16:49 被阅读0次

控制器的生命周期

就是问的viewController的生命周期,下面已经按方法执行顺序进行了排序

// 自定义控制器view,这个方法只有实现了才会执行
- (void)loadView
{
    self.view = [[UIView alloc] init];
    self.view.backgroundColor = [UIColor orangeColor];
}
// view是懒加载,只要view加载完毕就调用这个方法
- (void)viewDidLoad
{
    [super viewDidLoad];

    NSLog(@"%s",__func__);
}

// view即将显示
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    NSLog(@"%s",__func__);
}
// view即将开始布局子控件
- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    NSLog(@"%s",__func__);
}
// view已经完成子控件的布局
- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    NSLog(@"%s",__func__);
}
// view已经出现
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    NSLog(@"%s",__func__);
}
// view即将消失
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    NSLog(@"%s",__func__);
}
// view已经消失
- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];

    NSLog(@"%s",__func__);
}
// 收到内存警告
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];

    NSLog(@"%s",__func__);
}
// 方法已过期,即将销毁view
- (void)viewWillUnload
{

}
// 方法已过期,已经销毁view
- (void)viewDidUnload
{

}

触摸事件的传递

  • 触摸事件的传递是从父控件传递到子控件
  • 如果父控件不能接收触摸事件,那么子控件就不可能接收到触摸事件
  • 不能接受触摸事件的四种情况
    1. 不接收用户交互,即:userInteractionEnabled = NO
    2. 隐藏,即:hidden = YES
    3. 透明,即:alpha <= 0.01
    4. 未启用,即:enabled = NO
  • 提示:UIImageView的userInteractionEnabled默认就是NO,因此UIImageView以及它的子控件默认是不能接收触摸事件的
  • 如何找到最合适处理事件的控件:
    1. 首先,判断自己能否接收触摸事件
      • 可以通过重写hitTest:withEvent:方法验证
    2. 其次,判断触摸点是否在自己身上
      • 对应方法pointInside:withEvent:
    3. 从后往前(先遍历最后添加的子控件)遍历子控件,重复前面的两个步骤
    4. 如果没有符合条件的子控件,那么就自己处理

事件响应者链

  • 如果当前view是控制器的view,那么就传递给控制器
  • 如果控制器不存在,则将其传递给它的父控件
  • 在视图层次结构的最顶层视图也不能处理接收到的事件或消息,则将事件或消息传递给UIWindow对象进行处理
  • 如果UIWindow对象也不处理,则将事件或消息传递给UIApplication对象
  • 如果UIApplication也不能处理该事件或消息,则将其丢弃
  • 补充:如何判断上一个响应者
    • 如果当前这个view是控制器的view,那么控制器就是上一个响应者
    • 如果当前这个view不是控制器的view,那么父控件就是上一个响应者

描述下SDWebImage里面给UIImageView加载图片的逻辑

  • SDWebImage 中为 UIImageView 提供了一个分类UIImageView+WebCache.h, 这个分类中有一个最常用的接口sd_setImageWithURL:placeholderImage:,会在真实图片出现前会先显示占位图片,当真实图片被加载出来后在替换占位图片

  • 加载图片的过程大致如下:

    • 首先会在 SDWebImageCache 中寻找图片是否有对应的缓存, 它会以url 作为数据的索引先在内存中寻找是否有对应的缓存

    • 如果缓存未找到就会利用通过MD5处理过的key来继续在磁盘中查询对应的数据, 如果找到了, 就会把磁盘中的数据加载到内存中,并将图片显示出来

    • 如果在内存和磁盘缓存中都没有找到,就会向远程服务器发送请求,开始下载图片

    • 下载后的图片会加入缓存中,并写入磁盘中

    • 整个获取图片的过程都是在子线程中执行,获取到图片后回到主线程将图片显示出来

IBOutlet连出来的视图属性为什么可以被设置成weak?

  • 因为父控件的subViews数组已经对它有一个强引用
  • 使用storyboard创建的viewController,那么会有一个叫 _topLevelObjectsToKeepAliveFromStoryboard的私有数组强引用所有top level的对象,同时top level对象强引用所有子对象,那么vc没必要再强引用top level对象的子对象。

UIView和CALayer是什么关系?

  • UIView显示在屏幕上归功于CALayer,通过调用drawRect方法来渲染自身的内容,调节CALayer属性可以调整UIView的外观,UIView继承自UIResponder,比起CALayer可以响应用户事件,Xcode6之后可以方便的通过视图调试功能查看图层之间的关系
  • UIView是iOS系统中界面元素的基础,所有的界面元素都继承自它。它内部是由Core Animation来实现的,它真正的绘图部分,是由一个叫CALayer(Core Animation Layer)的类来管理。UIView本身,更像是一个CALayer的管理器,访问它的跟绘图和坐标有关的属性,如frame,bounds等,实际上内部都是访问它所在CALayer的相关属性
  • UIView有个layer属性,可以返回它的主CALayer实例,UIView有一个layerClass方法,返回主layer所使用的类,UIView的子类,可以通过重载这个方法,来让UIView使用不同的CALayer来显示,如:
  • (class) layerClass {
    // 使某个UIView的子类使用GL来进行绘制
    return ([CAEAGLLayer class]);
    }
  • UIView的CALayer类似UIView的子View树形结构,也可以向它的layer上添加子layer,来完成某些特殊的显示。例如下面的代码会在目标View上敷上一层黑色的透明薄膜。
    grayCover = [[CALayer alloc]init];
    grayCover.backgroudColor = [[UIColor blackColor]colorWithAlphaComponent:0.2].CGColor;
    [self.layer addSubLayer:grayCover];
    树形在系统内部被系统维护着三份copy
    • 逻辑树,就是代码里可以操纵的,例如更改layer的属性等等就在这一份
    • 动画树,这是一个中间层,系统正是在这一层上更改属性,进行各种渲染操作
    • 显示树,这棵树的内容是当前正被显示在屏幕上的内容
    • 这三棵树的逻辑结构都是一样的,区别只有各自的属性

loadView的作用?

  • loadView用来自定义view,只要实现了这个方法,其他通过xib或storyboard创建的view都不会被加载
  • 看懂控制器view创建的这个图就行


描述下SDWebImage里面给UIImageView加载图片的逻辑

  • SDWebImage 中为 UIImageView 提供了一个分类UIImageView+WebCache.h, 这个分类中有一个最常用的接口sd_setImageWithURL:placeholderImage:,会在真实图片出现前会先显示占位图片,当真实图片被加载出来后在替换占位图片
  • 加载图片的过程大致如下:
    • 首先会在 SDWebImageCache 中寻找图片是否有对应的缓存, 它会以url 作为数据的索引先在内存中寻找是否有对应的缓存
    • 如果缓存未找到就会利用通过MD5处理过的key来继续在磁盘中查询对应的数据, 如果找到了, 就会把磁盘中的数据加载到内存中,并将图片显示出来
    • 如果在内存和磁盘缓存中都没有找到,就会向远程服务器发送请求,开始下载图片
    • 下载后的图片会加入缓存中,并写入磁盘中
    • 整个获取图片的过程都是在子线程中执行,获取到图片后回到主线程将图片显示出来

相关文章

网友评论

      本文标题:iOS面试题-UI篇

      本文链接:https://www.haomeiwen.com/subject/coafvctx.html