iOS面试重点
2018-12-17 本文已影响91人
Fisland_枫
[TOC]
一 属性
快速问答
- delegate 属性为什么使用 weak ?
- 是为了避免循环引用
- xib/storybard连接的对象为什么使用weak?
- 因为控件的父控件view.superview已经strong reference了,所以对于controller只需要weak就可以
- 字符串 为什么使用copy?
- 因为复制问题,对于不可变我们使用copy,,我们希望的是内容的copy,不希望被外部改变同时还改变原有的内容
- Block 为什么使用 copy?
- block一开始是放在栈上面,只有copy之后才会放到堆上面。
更多内容 OC @Property属性
二 Runtime
什么是Runtime
- 简称运行时,就是系统在运行时候的一些机制,主要是消息机制
- 对于C语言,在编译期间已经确定好函数调用的顺序,没有二义性
- 但是OC函数调用为消息发送,属于动态调用过程。在编译时期不能决定真正调用的到底是哪个函数。
- 只有在运行时时候,根据函数的名称来找到对应的函数来调用
常用情况
- 动态的添加对象的成员变量和方法
- 动态交换两个方法的实现 Swimming method
- 拦截并替换方法
- 在方法上增加额外功能
- 实现NSCoding的自动归档和解档
- 实现字典转模型的自动转换 - MJExtension YYModel
三 RunLoop
RunLoop是什么
我们手机应用是事件驱动的整体架构,对于我们来说,理想的状态是:程序在激活状态下,没事就闲着,有事把它唤醒,接着就去分配执行事件,处理完了再去闲着,这样才不会占用资源。
RunLoop是线程的基础架构部分,每个线程都有自己的RunLoop对象,用来接收循环中的时间和安排的线程工作,并在没有工作时,让线程进入睡眠状态。
RunLoop作用
- 使得程序一直运行并能接受用户的事件输入
- 决定程序应该在何时处理事件(Event)
- 通用解耦(Message Queue),主调方和被调方
- 节省CPU资源
RunLoop的mode类型
- NSDefauleRunLoopMode :默认状态,不滑动,空闲状态下程序就会自动切换到这个mode
- UITrackingRunLoopMode :滑动状态
- UIInitializationRunLoopMode :私有的,可以追踪的,app启动的时候就是这个状态,第一个页面加载之后才回到defaultMode
- NSRunLoopCommonModes:默认状态下包括NSDefauleRunLoopMode和UITrackingRunLoopMode
详情可看
孙源@sunnyxx视频 RunLoop 介绍
YYKit 作者 深入理解RunLoop
四 NSThread、NSOperation、GCD
iOS有三种多线程方式,NSThread、NSOperation、GCD,越往后抽象程度越高,使用起来越简单,也是苹果越推荐
- NSThread, 最轻量级,相对简单,但是需要自己手动管理所有的线程活动,如生命周期,线程同步,睡眠等。
- NSOperation,自带线程周期管理。操作上可以更注重自己的逻辑,但是面向对象的抽象类,只能实现它或者它定义好的两个子类,NSInvocationOperation和NSBlockOperation
- GCD,最高效,避开并发陷阱。一般安全有简单可以使用NSOperation.而处理大量并发数据,
五 Block、Delegate、Notification
- Delegate
- 一对一,对同一个协议,一个对象只能设置一个代理,所以单例对象不能使用代理
- Notification
- 一对多,但是记得销毁。例子:登录成功
- Block
- 一对一,写法简练,更注重结果的传输,不要关注一些额外的东西。
- 需要注意循环引用
六 UDP、TCP、Socket、HTTP、POST、GET
UDP、TCP区别
| 区别 | TCP | UDP |
|---|---|---|
| 有无连接 | 面向连接的协议 | 五连接协议 |
| 可不可靠 | 可靠(丢包会自动重传) | 不可靠 |
| 有无序 | 有序(可以对其乱序的重排序) | 无序 |
| 有无界 | 无界(通过字节流传输) | 有界(每个包都是独立的) |
| 有无流量控制 | 流量控制(拥塞控制) | 没有 |
| 速度 | 传播慢(建立连接,保证可靠和有序比较耗时) | 传播快 |
| 大小 | 重量级,信息多,头部大(20个字节) | 轻量级,头部小(8个字节) |
| 基于的协议 | HTTP,Telent,FIP,SMTP | DNS,DHCP,SNMP,TFTP |
TCP三次握手
- 第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
- 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包,即SYN+ACK包,此时服务器进入SYN+RECV状态;
- 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次状态。
Socket和HTTP的区别
- HTTP是基于TCP连接的,是应用协议,主要解决如何包装数据;Socket是对TCP/IP协议的封装,本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。
- HTTP:短连接,客服端发起,服务端返回后断开连接,节省资源。服务端不能主动发起,(除非使用HTTP长连接技术);
- Socket:长连接,客服端可服务端使用Socket通信。保持连接通道,双方都可以自动发送数据,一般用于游戏,默认连接超时时间30秒,默认大小8k
GET、POST区别
- GET提交的数据会在地址栏显示出来,而POST提交,地址栏不会改变。
- GET请求能够被缓存, POST请求不能被缓存下来。
- GET请求会保存在浏览器的浏览记录中,POST请求不会保存在浏览器浏览记录中
- GET提交时,传输数据就会受到URL长度限制,POST由于不是通过URL传值,理论上书不受限。
- POST的安全性要比GET的安全性高;
七 简述内存分区情况
- 代码区:存放函数二进制代码
- 数据区:系统运行时申请内存并初始化,系统退出时由系统释放,存放全局变量、静态变量和常量
- 堆区:通过malloc等函数或new等操作符动态申请得到,需要程序员手动申请和释放。
- 栈区:函数模块内申请,函数结束时有系统自动释放。存放局部变量,函数参数。
栈和堆区别
- 栈的空间由操作系统自动分配/释放,堆上的空间手动分配/释放。
- 栈的空间是有限的,而对是很大的自由存储区
- C中的malloc函数分配的内存空间是在堆上的,C++中对应的new操作符。
- 程序在编译期对变量
区别下面指针的不同
- const char *p
- 定义了一个指向不可变的字符串的字符指针,可以这么看:const char *为类型,p是变量
- char const *p
- 与上一个一样
- char *const p
- 定义了一个指向字符串的指针,该指针值不可改变,即不可改变指向,这么看:char *是类型,const是修饰变量p,也就是p是一个常量
- const char * const p
- 定义了一个指向不可变的字符串的字符指针,且改指针也不可改变指向。这一个很容易看出来。两个const分别修饰,因此都是不可变的。
本文章
https://v.youku.com/v_show/id_XODgxODkzODI0.html?&request_count=1
https://juejin.im/entry/5785b2b6165abd0062ba2e06
https://juejin.im/post/5b4cd5aae51d455b5d3efa2c
- 定义了一个指向不可变的字符串的字符指针,且改指针也不可改变指向。这一个很容易看出来。两个const分别修饰,因此都是不可变的。