小知识点

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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 37.cocoa内存管理规则 1)当你使用new,alloc或copy方法创建一个对象时,该对象的保留计数器值为1...
    如风家的秘密阅读 827评论 0 4
  • 1.不可变数组转变为可变数组声明实例变量的数组 必须记得实现 对于遍历数组找到对象后 如果还需要查找 记得先结束 ...
    小新xin阅读 685评论 0 1
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 每个人都有迷失自己的时候,你也曾有吧。 午夜梦回,一颗心茫然失措,不知该去往何处。回想白天,看看夜晚,仿佛灵魂游离...
    可可豆_4b32阅读 144评论 0 0
  • 贵州首部商业微电影《私奔》2016年7月11日在优酷网上映。由贵州青年导演黄宗孟执导并主演,著名影视明星樊令出品并...
    贵州黄宗孟导演阅读 462评论 0 0