美文网首页
小知识点

小知识点

作者: iChuck | 来源:发表于2018-03-16 10:24 被阅读13次

UIButton 与 UITableView 的层级结构

  • 继承结构,属于内部的子控件结构
  • UIButton为:UIButton > UIControl > UIView > UIResponder > NSObject
  • UITableView为:UITableView > UIScrollView > UIView > UIResponder > NSObject

设置 ScrollView 的 contentSize 能在 ViewDidLoad 里设置吗?为什么?

  • 一般情况是可以在 ViewDidLoad 里设置,但是在 autolayout 下,系统会在 ViewDidAppear之前根据 subview 的 constraint 重新计算scrollview 的 contentsize。这就是为什么,在 Viewdidload 里面手动设置了 contentSize 没用。因为在后面,会再重新计算一次,前面手动设置的值会被覆盖掉。
  • 解决办法就是:
    • 去除 autolayout 选项,自己手动设置 contentsize
    • 如果要使用 autolayout,那么自己设置完 subview 的 constraint,然后让系统自动根据 constraint 计算出 contentsize。要么就在 Viewdidappear 里自己手动设置 contentsize

简述一下你对 UIView、UIWindow 和 CALayer 的理解

  • UIView:属于 UIKit.framework 框架,负责渲染矩形区域内容,为矩形区添加动画,响应区域的触摸事件,布局和管理一个或多个子视图。
  • UIWindow:属于 UIKit.framework 框架,是一个特殊的 UIView,通常在一个程序只会有一个 UIWindow,但可以手动创建多个 UIWindow,同时加到程序里去。UIWindow 在程序中主要起3个作用:
    • 作为容器,包含 app 所要显示的所有视图
    • 传递触摸消息到程序的 View 和其他对象
    • 与 UIViewController 协同工作,方便完成设备方向旋转的支持
  • CALayer:属于 QuartzCore.framework,是用来绘制内容的,对内容进行动画处理依赖与 UIView 来进行显示,不能处理用户事件。
  • UIView 和 CALayer 是相互依赖的,UIView 依赖 CALayer 提供内容,CALayer 依赖 UIView 的容器显示绘制内容。
  • UIViewController:每个视图控制器都有一个自带的视图,并且负责这个视图相关的一切事务。方便管理视图中的子视图,负责 Model 与 View 之间的通信,检测设备旋转以及内存警告;是所有视图控制类的积累,定义了控制器的基本功能

** frame 和 bounds 有什么不同?**

  • frame 指的是:该 View 在父View 坐标系统中的位置和大小(参照是父类的坐标系统)
  • bounds 指的是:该 View 在本身坐标系统中的位置和大小(参照点事本身坐标系统)

关于视图的声明周期的问题

  • 首先判断控制器是否有视图,如果没有通过 loadview 方法创建:通过 storyboard 或者代码
  • 随后调用 Viewdidload,可以进行下一步的初始化操作,只会被调用一次
  • 在视图显示之前调用 Viewwillappear,该函数可多次调用
  • 在布局变化后,调用 Viewwill、didLayoutSubviews 处理相关信息

响应者链条?

  • 事件响应链。包括点击事件,画面刷新等。在视图栈内从上至下,或者从下至上传播,可以说点事件的分发,传递以及处理。
  • 响应者链
    • UIResponder 类是 UIKit 中一个用于处理事件响应的基类。窗口上的所有事件触发,都由该类响应(即事件处理入口)。所以,窗口上的 View 及其控制器都是派生于该类的,例如 UIView、UIViewController
    • 调用 UIResponder 类提供的方法或者属性,我们就可以捕捉到窗口上的所有响应事件,并进行处理。
    • 响应者链条是由多个响应者对象连起来的链条,其中响应者对象是能处理事件的对象,所有的 View 和 ViewController 都是响应者对象,利用响应者链条能让多个控件处理同一个触摸事件。
  • 事件传递机制
    • 如果当前 View 不能处理当前事件,那么事件将会沿着响应链进行传递,直到遇到能处理该事件的响应者。

UITableView 的重用机制?

  • 查看 UITableView 头文件,会找到 NSMutableArray visiableCells,和 NSMutableArray reusableTableCell 两个结构
  • visiableCells内保存当前显示的 cells,reusableTableCell保存可重用的 cells
  • tableView 显示之初,reusableTableCell为空,那么 [tableView dequeueReusabelCellWithIdentifier:cellIdentifier]返回 nil;
  • 开始的 cell 都是通过 init 来创建,而且 cellForRowAtIndexPath 只是调用最大显示 cell 数的次数。比如:有100条数据,iPhone 一屏最多显示10个 Cell
  • 程序最开始显示 tableview 的情况是:
    • 用init 创建10个 cell,并给 cell 指定同样的重用标识(当然,可以为不同显示类型的 cell指定不同标识)。并且10个 cell 全部都加入到 visiableCells 数组,reusableTableCells 为空。
    • 向下拖动 tableview,当 cell 完全移除屏幕,并且 cell11(他也是 alloc 出来的,原因用上)完全显示出来的时候。cell11加入到 visiableCells,cell11移除 visiableCells,cell11 加入到 reusableTableCells。
    • 接着向下拖动 tableview,因为 reusableTableCells 中已经有值,所以当需要显示新的 cell,cellForRowAtIndexPath 再次调用的时候,[tableView dequeueReusabelCellWithIdentifier:cellIdentifier]返回 cell。cell1加入到 visiableCells,cell1移除 reusableTableCells;cell2移除 visiableCells,cell2加入到 reusableTableCells。之后再需要显示的 cell 就可以正常重用了。
    • 注意:配置 cell 的时候一定要注意,对取出的重用 cell 做重新赋值,不要遗留老数据。

UITableView 的性能优化?滑动的时候有种卡的感觉是为什么?怎么解决?

  • 在使用第三方应用时,却经常遇到性能上的问题,普遍表现在滑动时比较卡,特别是 cell 中包含图片的情况时。

  • 实际上针对性的优化就可以解决 tableview 滑动的时候卡顿的问题:

    • 使用不透明的视图。不透明视图可以提高渲染的速度。可以将 cell 及其子视图的 opaque 属性设置为 YES(默认值)。
    • 不要重复创建不必要的 cell。UITableView 只需要一屏幕的 UITableViewCell 的对象即可。因此在 cell 不见的时,可以将其缓存起来,而在需要时继续使用它即可。注意:cell 被重用时,需要调用 setNeedsDisplayInRect:或 setNeedsDisplay 方法重绘cell。
    • 减少动画效果的使用,最好不要使用 insertRowsAtIndexPath:withRowAnimation:方法,而是直接调用 reloadData 方法。
    • 减少视图的数目。cell 包含了 textLabel、detailTextLabel 和 imageView 等 View,而你还可以自定义一些视图放在它contextView 里,创建它会消耗较多的资源,并且也影响渲染的性能。
    • cell 包含图片,且数目较多,使用自定义 cell 速度比默认的要快。继承 UITableViewCell,重写 drawRect 方法:不过这样以来,你会发现选中一行后,这个 cell 就变蓝了,其中的内容就被遮挡住了。最简单的办法就是将 cell 的 selectionStyle 属性设置为 None,这样就不会高亮了。不需要与用户交互的时候,使用 CALayer,将内容绘制到 layer 上,然后对 cell 的 contextView.layer 调用 addSubLayer方法。这个例子中,layer 并不会显著影响性能,但如果 layer 透明,或者有圆角、变形等效果,就会影响绘制速度了。解决办法可以使用预渲染图像。
    - (void)drawRect:(CGRect)rect {
        
        if (image) {
            [image drawAtPoint:imagePoint];
            self.image = nil;
        } else {
            [placeHolder drawAtPoint:imagePoint];
        }
        
        [text drawInRect:textRect withFont:font lineBreakModel:UILineBreakModelTailTruncation];
    }
    
    • 不要做多余的绘制工作。 在实现 drawRect:的时候,它对 rect 参数就是需要绘制的区域,这个区域以外的不需要进行绘制。
    • 预渲染图像。你会发现即使做到了上述几点,当新的图像出现时,仍然会有短暂的停顿现象。解决的办法就是在图形上下文中画,导出 UIimage 对象,然后再绘制到屏幕。(头像圆角,或者其他变形的时候,用图形上下文能提高性能。)异步绘制。
    • 不要阻塞主线程。tableView 在更新数据的时候,整个界面卡主不动,完全不响应应用的用户请求。常见的是网络请求,等待时间长。解决方案:使用多线程,让子线程去执行这些函数或方法。
    • 注意:当下载线程数超过2时,会显著影响主线程的性能所以在不需要响应用户请求的时,下载线程数可以增加到5,不建议再加了,以加快下载速度。如果用户正在交互,应把线程数量控制在2个以内。
    • 提前计算并缓存好高度。因为 heightForRowAtIndexPath 调用非常频繁
    • 选中正确的数据结构:学会选中对业务场景最适合的数组结构是写出高效代码的基础。如果,数组:有序的一组值。使用索引来查询比较快,使用值查询很慢,插入、删除很慢。字典:存储键值对,用键查找比较快。集合:无序的一组值,用值来查询很快,插入、删除很快。
    • gzip、zip 压缩:当从服务器下载相关附件时,可以通过 gzip、zip 压缩后再下载,使得内存更小,下载速度更快。

tableview 的 cell 如何嵌套 collectionView?

  • 思路用网易新闻类似,用自定义的继承 UITableViewCell 的类,在 initWithFrame 的构造方法中,初始化自定义的继承自 UICollectionView

下拉和上拉的原理

  • 以 tableView 的上拉刷新为例:
    • 为了进行无缝阅读,通过 tableView 的代理方法,willDisplayCell 判断是否是最后一行
    • 如果是最后一行,在显示最后一行的同时,判断当前是否存在上拉刷新
    • 如果没有上拉刷新,就进行加载数据,启动小菊花
  • 以 tableView 下拉刷新为例
    • 判断当前的上拉刷新视图是否有动画
    • 如果没有动画,就不是上拉刷新
    • 然后下拉刷新加载数据
    • 加载完毕数据关闭数据

如何实现 cell 的动态行高?

  • 如果希望每条数据显示自身的高,必须设置两个属性,1.预估行高,2.自定义行高
  • 设置预估行高 _tableView.estimatedRowHeight = 200;
  • 设置自定义行高 _tableView.rowHeight = UITableViewAutomaticDimension;
  • 如果让自定义行高有效,必须让容器视图有一个自下而上的约束

谈谈 webview

  • iOS 开发中 webview 和 native code 的配合使用的一些经验和技巧。
  • webview 与运维成本低,更新几乎不依赖 App 的版本,但在交互和性能上与 native code 有很大的差距。
  • native code 与之对应。
  • h5确实给 web 带入了一个新时代。这个时代是什么?web App。也就是说,只有脱离 native 的这个前提,在浏览器的环境下,h5的意义才鞥呢显现

awakeFormNib 与 viewdidload 区别

  • awakeFromNib:当.nib 文件被加载的时候,会发送一个 awakeFromNib 消息到 nib 文件中的没个对象,每个对象都可以定义自己的awakeFromNib函数来响应这个消息,执行必要操作。也就是说 nib 文件创建 View 对象执行awakeFromNib
  • viewdiidload:当 View 对象被加载到内存就会执行 Viewdidload,不管是通过 nib 还是代码形式,创建对象就会执行 viewdidload

layoutSubview 何时调用?

  • 初始化 init 方法时不会触发
  • 滚动 UIScrollView 触发
  • 旋转屏幕触发
  • 改变 View 的值触发,前提是 frame 改变了
  • 改变 UIView 的大小触发

viewcontroller 的 didReceiveMemoryWarning在什么时候调用,默认操作是什么?

  • 引用程序收到来自系统的内存警告的时候,调用didReceiveMemoryWarning方法
  • 默认做法:控制器上的 View 不再窗口上显示时,调用 ViewWillUnload,直接销毁View,并调用ViewDidUnload

如何实现瀑漂流,流水布局

  • 使用 UICollectionView
  • 使用自定义的 FlowLayout
  • 需要在 layoutAttributeForElementsInRect 中设置自定布局的 item 的 frame
  • 在 prepareLayout 中计算布局
  • 遍历数据内容,根据索引取出对应的 attributes(使用 LayoutAttributesForCellWithIndexPath),根据九宫格算法设置布局
  • 细节1:实际布局,重写shouldInvalidateLayoutForBoundsChange(bounds 改变从新布局,scrollView 的 contextOffset>bounds)
  • 细节2:计算设置 itemSize(保证内容显示完整,UICollectionView 的 context size 是根据 itemsize 计算的)根据列最大高度、对应列数量求出,最大高度累加得到
  • 细节3:追加 item 到最短列,避免底部参数不齐

实现突破轮播图

  • scrollView 只需要设置三个 imageView 即可,并且默认显示中间的 imageView
  • 根据 scrollView 的移动情况,迅速变化三个 imageView 中的图片数据
  • imageView 更新完毕后,偷偷把 scrollView 拉回到中间的imageView 位置,这样视觉效果上就实现了无限循环的效果。

load initialize 方法的区别

    • (void)load;
      • 当类对象被加入项目时,runtime 会向每个类发送 load 消息
      • load 方法绘制每个类甚至分类被引入时仅调用一次,调用的顺序:父类优先于子类,子类优先于分类。
      • load 方法不会被类自动继承
    • (void)initialize;
      • 也是在第一次使用这个类的时候会调用这个方法。

如何播放 gif 图片,有什么优化方案??

  • UIImageView 用来显示图片,使用 UIImageView 中的动画数组来实现动画效果
  • 用 UIWebView 来显示动态图片
  • 第三方框架

事件传递与响应的过程?

  • 在产生一个事件时,系统会将该事件加入到一个由 UIApplication 管理的事件队列里去,UIApplication 会从事件队列中取出最前面的事件,将它传递给先发送事件给应用程序的主窗口。
  • 主窗口会调用 hitTest 方法寻找最适合的视图控件,找到后会调用控件的 touches 方法来做具体的事情。
  • 当调用 touches 方法,它的默认做法,就会将事件顺着响应者链条上往上传递,传递给上一个响应者,接着就会调用上一个响应者的 touches 方法。

有哪些常见的 crash 场景?

  • 访问了僵尸对象
  • 访问了不存在的方法
  • 数组越界
  • 在定时器下一次回调前将定时器释放掉

LLDB(GDB)常用的调试命令?

  • p 输出基本类型
  • po 输出 oc 对象
  • expr 可以在调试中执行表达式,并打印结果

如果一个函数10中有7次正确,3次错误,问题可能出现在什么地方?

  • 从函数的所有条件分支类分析可能的错误。
  • 检测函数参数是否存在异常。

如何对 iOS 设备进行性能测试?

  • profile->instruments->Time Profile 进行性能测试
  • App 使用过程中,接听电话。
  • App 使用过程中,收到推送。
  • 设备充电时,App 的影响以及流畅度。
  • 设备在不同电量(低于10%、50%、95%)时,App 的响应以及流畅度
  • 意外断电,App 数据丢失情况。
  • 网络变化时,App 是如何响应的。
  • 多点触摸的情况。
  • 跟其他 App 之间进行交互时的响应。
  • 杀死进程在重新打开的反馈
  • iOS 系统语言环境的变化

AFNetworking 断点续传

  • 断点续传的主要思路:
    • 检查服务器的文件信息
    • 检查本地文件
    • 如果比服务器小,断点续传,利用 HTTP 请求头的 Range实现断点续传
    • 如果比服务器大,重新下载
    • 如何一样,下载完成

简单描述一下客户端的缓存机制?

  • 缓存可以分为:内存数据缓存、数据库缓存、文件缓存
    • 每次想获取数据的时候
    • 先检测内存中有无缓存数据
    • 在检测本地有无缓存数据(数据库、文件)
    • 最终发送网络请求
    • 将服务器返回的网络数据进行缓存(内存、数据库、文件)

什么时候序列化和反序列化,用来做什么

  • 序列化把对象转化为字节序列的过程
  • 反序列化把直接序列恢复成对象
  • 把文件写到文件或者数据库中,并读取出来

iOS 中常用的数据存储方式有哪些?

  1. 数据存储方法:UserDefault、KeyChain、File、DB
  2. file:Plist、Archiver、Stream
  3. DB:Core Data、FFDB

相关文章

  • android 常用小知识点 tips (二)

    android 常用小知识点 tips (一)android 常用小知识点 tips (二) 持续更新中.... ...

  • js小知识点

    js小知识点 整理 js小知识点 (一):获取元素 1:document.getElementById('id名'...

  • 编程中的小tips

    perl 小知识点 defined () 哈希的长度 数组的uniq R 小知识点 rowMeans() 和 co...

  • 无标题文章

    综和复习本月知识点总结: 一:微信小程序 二:vue复习 三:js复习 四:新知识点 一:微信小程序知识点总结 开...

  • 小知识点集汇一

    小知识点集汇一 小知识点 node接口模拟返回 js接口模拟数据 mockjs mocha js 测试框架--教程...

  • 监听回车按键小知识点整理

    监听回车按键小知识点

  • 两年iOS经验之你忽略的小知识点

    两年iOS经验之你忽略的小知识点 两年iOS经验之你忽略的小知识点

  • 小知识点

    Window 运行输入 winver 可以查看 当前系统版本号 ipconfig 查看本机IP地址 Unity U...

  • 小知识点

    时间格式化 托管项目到线上仓库 基本使用方法使用git init初始化本地项目使用touch README.md ...

  • 小知识点

    Axure 做滚动视图拉一个内联框架,将内联框架的url设置为另外一个网页

网友评论

      本文标题:小知识点

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