iOS知识点总结

  • 多线程有哪几种,常见的应用场景
  • SDWebImage的原理和实现机制
  • 事件的传递和响应机制
  • UITableView的卡顿优化
  • ARC原理以及和MRC区别及autoreleasePool的原理
  • block、代理、通知的区别,block的用法需要注意些什么
  • @property有哪些属性,它们的区别和作用
  • 浅拷贝和深拷贝
  • static关键字的作用
  • 线程和进程的区别和联系
  • 堆和栈的区别
  • objc的内存管理
  • 动态绑定
  • ViewController的生命周期
  • OC和Swift的区别和联系,各自的优缺点
  • 类别、继承、扩展的区别、优缺点
  • KVO和KVC
  • 数据持久化方式
  • 循环引用出现的场景
  • 运行时机制的原理和应用场景
  • Core Audio和Audio Queue、AVPlayer视频播放(http://sky-weihao.github.io/2015/10/06/Video-streaming-and-caching-in-iOS/)
  • React Native
  • Html5
  • 沙盒机制
  • 单例的写法,在单例中创建数组应该注意什么
  • git和svn的简单用法以及简单的几个命令
  • 友盟报错可以查看到某一行的错误,原理是什么
  • 请求服务器的方式,它们之间的区别是什么
  • Instruments检测电池电量和内存消耗的用法
  • 自定义过的控件
  • __block和__weak修饰符的区别
  • UIResponder的继承链
  • Http常见状态码
  • frame和bounds
  • nil、Nil、NULL区别
  • TCP和UDP区别和联系
  • Socket建立网络连接的步骤
  • 防止指针越界问题
  • sprintf,strcpy,memcpy使用上有什么要注意的地方
  • 链表与数组的区别与联系

*多线程有哪几种,常见的应用场景

Pthreads、NSTread、GCD、NSOperation

  • Pthreads:Posix threads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API,适用于类Unix操作系统。是基于C语言的框架。手动管理线程的生命周期。
  • NSTread:完全面向对象的,需手动管理线程的生命周期(一般用于调试,[NSTread currentTread]可获取当前线程类,从而获知当前线程的各种属性)。
  • GCD:Grand Central Dispatch,苹果为多核的并行运算提出的解决方案,所以会自动合理的利用更多的CPU内核,可自动管理线程的生命周期(创建线程、调度任务、销毁线程)。它使用的也是c语言,但是使用了block,所以使用起来很方便、而且灵活。
    任务有两种执行方式:同步和异步(是否阻塞当前线程)
    主队列用于刷新UI,一般耗时的任务都要放到别的线程执行
  • NSOperation和NSOperationQueue:将要执行的任务封装到一个NSOPeration(NSInvocationOperation或NSBlockOperation或自定义继承NSOperation类的Operation并实现其main和cancel方法)对象中,然后添加到NSOperationQueue中。

* SDWebImage的原理和实现机制

  • 先把placeholder Image显示,然后SDWebImageManager根据URL开始处理图片;
  • 接着从缓存查找图片是否已经下载,如果已下载则通过代理回调到前端展示图片;
  • 如果内存缓存中没有,生成NSInvocationOperation添加到队列中开始查找硬盘中是否已经缓存,如果读取到了图片将图片添加到缓存中,进而回调展示图片;
  • 否则需要由SDWebImageDownloader下载图片,NSURLConnection来做,下载完后交给SDWebImageDecoder做图片解码处理(是在NSOperationQueue中处理,如果需要对图片二次处理也在这里完成,效率会好很多),然后通知所有的下载代理下载完成,回调给需要展示的地方展示;
  • 将图片保存到SDImageCache中,内存缓存和硬盘缓存同时保存。写文件时也以单独的NSInvocationOperation完成,避免拖慢主线程;
    SDImageCache初始化时会注册一些消息通知,在内存警告或退到后台时清理内存图片缓存,应用结束的清理过期图片。

* 触摸事件的传递和响应者链机制

1、触摸事件的传递
  • 发生触摸事件后,系统会将该事件加入到一个UIApplication管理的事件队列
  • UIApplication会从事件队列中取出最前面的事件,先发送给应用程序的主窗口keyWindow
  • 主窗口会在视图层级结构中找到一个最合适的视图来处理触摸事件,找到合适的视图控件,会调用touches方法作具体的事件处理
  • 事件的传递即:产生触摸事件->UIApplication事件队列->[UIWindow hitTest:withEvent:]->返回更合适的view->[子控件 hitTest:withEvent:]->返回最合适的view
  • 如何找到最合适的控件来处理事件:
    1)首先判断主窗口自己能否接受触摸事件
    2)判断触摸点是否在自己身上
    3)子控件数组中从后往前遍历子控件,遍历时重复步骤1)、2)
    4)找到fitview以后,把事件交给这个fitview,再遍历这个fitview的子控件,直至没有更合适的view为止
    5)如果没有符合条件的子控件,那么就认为自己是最合适的view
  • UIView不能接收触摸事件的三种情况(UIImageView默认不允许交互,可设置成可交互):
    1)不允许交互:userInteractionEnabled = NO
    2)隐藏:如果父控件隐藏,那么子控件也会隐藏
    3)透明度:如果设置一个控件的透明度<0.01(透明),会直接影响子控件的透明度
    *寻找最合适的view底层剖析
    两个重要方法:
    hitTest:withEvent:方法(事件传递给该控件时调用,可重写该方法,返回指定view作为合适的view作为拦截事件的处理->建议在父控件的hitTest:withEvent:中返回子控件作为最合适的view)
    pointInside方法 判断点是否在当前view上
2、响应者链
  • 响应者链的事件传递过程
    1)如果当前view是控制器的view,那么控制器就是上一个响应者,事件就传递给控制器;否则父视图就是上一响应者,事件就传递给它的父视图
    2)如果视图层级的最顶级视图也不能处理收到的事件或消息,则将事件或消息传递给UIWindow对象进行处理
    3)再者就要传递给UIApplication对象
    4)如果UIApplication也不能处理该事件或消息,则将其丢弃
3、事件处理的整个流程总结:

1)触摸屏幕产生触摸事件后,触摸事件会被添加到由UIApplication管理的事件队列中(即,首先接收到事·件的是UIApplication)。
 2)UIApplication会从事件队列中取出最前面的事件,把事件传递给应用程序的主窗口(keyWindow)。
 3) 主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件。(至此,第一步已完成)
 4)最合适的view会调用自己的touches方法处理事件
 5)touches默认做法是把事件顺着响应者链条向上抛。

* ARC原理以及和MRC区别及autoreleasePool的原理

  • ARC即自动引用计数,由编译器在程序需要的地方自动加入retain/release,不需要手动管理内存(iOS5/Mac OSX 10.7开始引入)
  • MRC即手动管理内存,自己负责系统变量的release和retain操作,做到谁分配谁释放,alloc/retain要和release的数量相对应。函数返回对象时要autorelease
  • autoreleasePool:调用autorelease的对象会加入自动释放池中,等到自动释放池drain时,池中变量收到release消息

* UITableView的卡顿优化

  • cell的重用
  • 避免cell的重新布局,可将cell单独放到一个自定义类,初始化时就布局好
  • 提前计算并缓存cell的属性及内容
  • 背景色不要使用clearcolor,透明度也不要设置为0(渲染耗时长)
  • 刷新的尽量更新局部,reloadsection
  • 加载网络数据或图片的时候使用异步加载,并缓存
  • 按需加载,cell滚动很快时,只加载最终显示范围内的cell
  • 不用实现无用的代理,tableView只遵守两个协议
  • 缓存行高:estimatedHeightForRow不能和HeightForRow里面的layoutIfNeed同时存在,这两者同时存在才会出现“窜动”的bug。所以我的建议是:只要是固定行高就写预估行高来减少行高调用次数提升性能。如果是动态行高就不要写预估方法了,用一个行高的缓存字典来减少代码的调用次数即可
  • Instrument里的Core animation逐项检查,滑动时的帧数等等

* block、代理、通知的区别,block的用法需要注意些什么

  • 代理是一对一的关系,并且接收方可以给发送方返回值
    *通知是一对多的关系,且接收方不可给发送方返回值

@property有哪些属性,它们的区别和作用

  • 原子性
  • 读写权限
  • 方法名getter==、setter==属性
  • 内存管理语义
  • copy是复制的内容,保持属性不受外界影响,不论传入的是可变对象还是不可变对象,本身持有的都是不可变的副本

* 浅拷贝和深拷贝

  • 对集合类对象的copy操作:copy是指针拷贝,mutableCopy是内容拷贝,此处的内容拷贝,数组中的元素依旧是指针拷贝
  • 对非集合类对象的copy操作:对 immutable 对象进行 copy 操作,是指针复制,mutableCopy 操作时内容复制;对 mutable 对象进行 copy 和 mutableCopy 都是内容复制

* static关键字的作用

  • 作用于变量:用static声明局部变量,使其变为静态存储方式(静态数据区),作用域不变;用static声明外部变量,其本身就是静态变量,这只会改变其连接方式,使其只在本文件内部有效,而其他文件不可连接或引用该变量。
  • 作用于函数:对函数的连接方式产生影响,使得函数只在本文件内部有效,对其他文件是不可见的。这样的函数又叫作静态函数。使用静态函数的好处是,不用担心与其他文件的同名函数产生干扰,另外也是对函数本身的一种保护机制。使用extern关键字,表示该函数是外部函数,可供其他文件调用
  • const修饰变量是表示它修饰的变量值是不可变的。
    将const改为外部连接,作用于扩大至全局,编译时会分配内存,并且可以不进行初始化,仅仅作为声明,编译器认为在程序其他地方进行了定义( extend const int ValueName = value)

* 线程和进程的区别和联系

  • 线程和进程都是操作系统中程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性
  • 不同的操作系统资源管理方式,进程有自己独立的地址空间,一个进程崩溃后,在保护模式下,其他进程不会受到影响。而线程只是进程中的不同执行路径,线程有自己的堆栈和局部变量,但线程之间没有独立的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

* 堆和栈的区别

  • 堆:手动管理生命周期,地址区块由低地址向高地址扩展,且可不连续,获得空间比较灵活也比较大
  • 栈:编译器自动管理,由高地址向低地址扩展且连续,编译时已申请好内存区块的大小

* objc的内存管理

  • 谁分配和初始化创建了对象,谁就拥有了该对象,从而也要负责该对象的释放
  • 如果拷贝了一个对象,就拥有了拷贝得到的对象,要负责释放该对象
  • 如果保持了一个对象,则在不需要的时候释放改对象

*动态绑定

  • 动态绑定将调用方法的确定也推迟到运行时

* ViewController的生命周期

-init-loadView-viewDidload-viewWillAppear-viewWillLayoutSubviews-viewDidLayoutSubviews-viewDidAppear-viewWillDisappear-viewDidDisappear-viewWillUnload-viewDidUnload-dealloc

* OC和Swift的区别和联系,各自的优缺点

  • Swift:没有main函数,程序自上而下执行;没有分号;类型自行推断,只有常量和变量之分;BOOL值类型更严格,不再是OC的非0就是真,Swift的true才是真,false是假;可以多对多赋值;if语句必须要有大括号;一个类只有一个文件;有溢出运算符,防止数据溢出;元祖类型var point = (x:15,y:20.2);
    代码简洁高效,开发效率高
    高级的语法特性(类型推断、泛型、函数式语言特性、闭包)

  • OC :objc优缺点:

    1. Cateogies
    2. Posing
    3. 动态识别
    4. 指标计算
      5)弹性讯息传递
    5. 不是一个过度复杂的 C 衍生语言
    6. Objective-C 与 C++ 可混合编程
      缺点:
    7. 不支持命名空间
    8. 不支持运算符重载
      3)不支持多重继承
      4)使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣。

* 数据持久化方式

文件写入、数据库、Core Data、对象归档

* 循环引用出现的场景

计时器、block、delegate

* 运行时机制的原理和应用场景

*类别中动态添加属性
*获取对象的成员列表,通过kvc将数据转模型
*交换方法:在AFNetworking中,替换了NSURLSession resume,每次发送网络请求的时候,都会发送通知,截取信息。

* React Native

  • 用javascript去写iOS的原生应用
    *优点是:Native不用WebView,彻底摆脱了WebView让人不爽的交互和性能问题;
    Native的原生控件有更好的体验;
    Native有更好的手势识别;
    Native有更适合的线程模型;
    缺点是:还在试用阶段,潜在的问题尚不得而知:兼容性问题,性能问题等。还没大量普及,学习资料尚且不多,供爱折腾的朋友尝尝鲜。

  • 沙盒机制
    Document、Library、tmp

  • Document:用于存储用户数据。iTunes备份和恢复的时候会包括此目录。程序中建立的或在程序中浏览到的文件数据
    *Library:caches:用户需要缓存的文件;preferences:App的偏好设置,可通过NSUserDefaults读取和设置
    *保存一些退出应用就可清除的数据

* Http常见状态码

  • 302请求重定向
  • 500以上服务器错误
  • 400以上请求链接错误或找不到服务器
  • 200以上请求成功
  • 100以上是请求接受成功

*友盟报错可以查看到某一行的错误,原理是什么

dSYM UUID,这个是dSYM文件的唯一标识。dSYM 是保存 16 进制函数地址映射信息的中转文件,我们调试的 symbols 都会包含在这个文件中,并且每次编译项目的时候都会生成一个新的 dSYM 文件。根据内存地址找到对应的代码

*git和svn的简单用法以及简单的几个命令

  • git clone、git pull、git log、git branch

*TCP和UDP区别和联系

  • 即传输层协议
  • TCP:面向连接、传输可靠(保证数据正确性,保证数据顺序)、用于传输大量数据(流模式)、速度慢,建立连接需要开销较多(时间,系统资源)。
  • UDP:面向非连接、传输不可靠、用于传输少量数据(数据包模式)、速度快。
  • TCP是一种流模式的协议,UDP是一种数据包模式的协议。

*Socket建立网络连接的步骤

socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。

*数据库,数据迁移

realm,只要表的结构有变化,把当前的数据库版本加1,realm会根据schemaVersion自动迁移数据

*局部变量、实例变量的释放时机

  1. 局部变量出了方法就会被释放
  2. 实例变量取决于指向它的指针,如果没有强引用指针指向它,页面被销毁后指针被销毁,对象随之释放

*推送的原理

  1. 客户端把udid和bundleid发送给苹果的apns服务器,服务器生成一个deviceToken返回给客户端,客户端把deviceToken传给我们的后台服务端,服务端把deviceToken存储到数据库里,一旦有新的信息需要推送,后台服务端就会去数据库查询该deviceToken的信息,通知apns服务器给该deviceToken发送什么样的信息,apns服务器根据deviceToken找到这台设备并推送通知

*setNeedsLayout和layoutIfNeeded

setNeedsLayout:标记为需要重新布局,异步调用layoutIfNeeded,在下一轮runloop结束前刷新所有的布局和UI上的更新。
layoutIfNeeded:如果有标记,立即调用layoutSubviews进行布局,如果没有则不会调用layoutSubviews

你可能感兴趣的:(iOS知识点总结)