├── .all-contributorsrc ├── .github └── workflows │ └── blank.yml ├── .gitignore ├── README.md ├── _index.md ├── docs ├── ch01 │ ├── tc01 │ │ ├── 01.md │ │ └── 01 │ │ │ ├── 011.jpg │ │ │ ├── 012.jpg │ │ │ └── tcp_congestion.png │ ├── tc02 │ │ └── 02.md │ ├── tc03 │ │ └── 03.md │ └── tc04 │ │ └── 04.md ├── ch04 │ ├── tc01 │ │ ├── 412 │ │ │ └── 1.png │ │ ├── 414 │ │ │ └── 1.png │ │ ├── 4-1-1.md │ │ ├── 4-1-2.md │ │ ├── 4-1-3.md │ │ ├── 4-1-4.md │ │ ├── 4-1-5.md │ │ └── 4-1-6.md │ ├── tc02 │ │ └── 4-2-1.md │ └── tc03 │ │ ├── 4-3-1.md │ │ ├── 4-3-2.md │ │ └── 4-3-3.md ├── ch05 │ ├── tc01 │ │ ├── 5-1-1.md │ │ ├── 5-1-2.md │ │ ├── 5-1-3.md │ │ └── 5-1-4.md │ ├── tc02 │ │ ├── 5-2-1.md │ │ ├── 5-2-2.md │ │ ├── 5-2-3.md │ │ └── 5-2-4.md │ └── tc03 │ │ ├── 5-3-1.md │ │ └── 5-3-2.md ├── ch06 │ ├── tc01 │ │ ├── 6-1-1.md │ │ ├── 6-1-2.md │ │ ├── 6-1-3.md │ │ ├── 6-1-4.md │ │ ├── 6-1-5.md │ │ ├── 6-1-6.md │ │ ├── 6-1-7.md │ │ ├── 6-1-8.md │ │ └── 6-1-9.md │ ├── tc02 │ │ ├── 6-2-1.md │ │ ├── 6-2-2.md │ │ ├── 6-2-3.md │ │ └── 6-2-4.md │ └── tc03 │ │ ├── 6-3-1.md │ │ ├── 6-3-2.md │ │ ├── 6-3-3.md │ │ └── 6-3-4.md ├── ch07 │ ├── tc01 │ │ └── 7-1-1.md │ ├── tc02 │ │ └── 7-1-2.md │ ├── tc03 │ │ └── 7-1-3.md │ ├── tc04 │ │ └── 7-1-4.md │ ├── tc05 │ │ └── 7-1-5.md │ └── tc06 │ │ └── 7-2-1.md ├── ch08 │ └── tc01 │ │ ├── 8-1-1.md │ │ ├── 8-1-2.md │ │ ├── 8-1-3.md │ │ ├── 8-1-4.md │ │ ├── 8-1-5.md │ │ ├── 8-1-6.md │ │ ├── 8-1-7.md │ │ ├── 8-1-8.md │ │ └── 8-1-9.md ├── ch09 │ └── tc01 │ │ ├── 912 │ │ ├── 1.png │ │ ├── 2.png │ │ └── 3.png │ │ ├── 914 │ │ ├── 1.png │ │ └── 2.png │ │ ├── 9-1-1.md │ │ ├── 9-1-10.md │ │ ├── 9-1-2.md │ │ ├── 9-1-3.md │ │ ├── 9-1-4.md │ │ ├── 9-1-5.md │ │ ├── 9-1-6.md │ │ ├── 9-1-7.md │ │ ├── 9-1-8.md │ │ └── 9-1-9.md └── ch10 │ └── tc01 │ ├── 10-1-1.md │ ├── 10-1-2.md │ ├── 10-1-3.md │ └── 10-1-4.md ├── menu └── index.md ├── package.json └── yarn.lock /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "interval-content", 3 | "projectOwner": "idevqa", 4 | "repoType": "github", 5 | "repoHost": "https://github.com", 6 | "files": [ 7 | "README.md", 8 | "_index.md" 9 | ], 10 | "imageSize": 60, 11 | "commit": true, 12 | "commitConvention": "none", 13 | "contributors": [ 14 | { 15 | "login": "Desgard", 16 | "name": "Gua", 17 | "avatar_url": "https://avatars3.githubusercontent.com/u/7804535?v=4", 18 | "profile": "https://www.desgard.com/", 19 | "contributions": [ 20 | "content" 21 | ] 22 | }, 23 | { 24 | "login": "dengchaojie", 25 | "name": "邓超界_dengChaoJie", 26 | "avatar_url": "https://avatars1.githubusercontent.com/u/13744851?v=4", 27 | "profile": "https://juejin.im/user/590062eeda2f60005ddf10bd", 28 | "contributions": [ 29 | "content" 30 | ] 31 | }, 32 | { 33 | "login": "xilin", 34 | "name": "Xi Lin", 35 | "avatar_url": "https://avatars1.githubusercontent.com/u/543395?v=4", 36 | "profile": "https://github.com/xilin", 37 | "contributions": [ 38 | "content" 39 | ] 40 | }, 41 | { 42 | "login": "0x1306a94", 43 | "name": "0x1306a94", 44 | "avatar_url": "https://avatars3.githubusercontent.com/u/14822396?v=4", 45 | "profile": "https://blog.0x1306a94.com", 46 | "contributions": [ 47 | "content" 48 | ] 49 | }, 50 | { 51 | "login": "TifaTsubasa", 52 | "name": "YuriTT", 53 | "avatar_url": "https://avatars2.githubusercontent.com/u/9051625?v=4", 54 | "profile": "http://blog.upmer.com/", 55 | "contributions": [ 56 | "content" 57 | ] 58 | }, 59 | { 60 | "login": "XuYanci", 61 | "name": "XuYanCi @许还真", 62 | "avatar_url": "https://avatars1.githubusercontent.com/u/10784657?v=4", 63 | "profile": "https://yanci.me", 64 | "contributions": [ 65 | "content" 66 | ] 67 | }, 68 | { 69 | "login": "WhoJave", 70 | "name": "WhoJave", 71 | "avatar_url": "https://avatars3.githubusercontent.com/u/12373088?v=4", 72 | "profile": "https://github.com/WhoJave", 73 | "contributions": [ 74 | "content" 75 | ] 76 | } 77 | ], 78 | "contributorsPerLine": 7, 79 | "skipCi": true 80 | } 81 | -------------------------------------------------------------------------------- /.github/workflows/blank.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Ready for Repo 18 | run: | 19 | curl -XPOST -u "${{ secrets.USERNAME}}:${{secrets.PAT_TOKEN}}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/idevqa/interval/dispatches --data '{"event_type": "build_application"}' 20 | 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | yarn-error.log -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # iOS 面试题词条库 4 | 5 | 6 | [![All Contributors](https://img.shields.io/badge/all_contributors-7-orange.svg?style=flat-square)](#contributors-) 7 | 8 | 9 | 10 | **链接:https://iosgua.com/interval/** 11 | 12 | ## 为什么会整理这套面试题? 13 | 14 | 其实是在公众号群里,各路朋友的呼声。毕竟关注技术的多数人是为了找到一个好工作,能够进心仪的大厂。所以希望制作一个面试题的词条收集,让大家一起参与编辑。 15 | 16 | 很多知识的答案是不断的讨论才能得出结论,且这些结论其实都是具有时效性的,例如 Apple 的 Runtime 特性、Swift 各种语法的优雅写法等,前者会随着 Runtime 仓库的版本迭代而变化,后者则会随着 Swift 语言的版本更替而改变。 17 | 18 | ## 如何参与面试题整理? 19 | 20 | 可以直接向内容仓库 [interval-content](https://github.com/idevqa/interval-content) 提 Pull Request 进行修改编辑申请。另外一个简单的方法,在每个词条问题页面中的左下角位置,都会有 `Edit this page` 的按钮,会直接打开 GitHub 编辑页面。如此可以快速发起 PR,当 @冬瓜 或者其他管理员 Review 通过后,方可合入词条。 21 | 22 | ## 适用人群 23 | 24 | iOS 方向求职应届生以及考虑机会的 iOS 工程师。 25 | 26 | ## 特别感谢 27 | 28 | 感谢以下题目来源: 29 | 30 | * [阿里、字节:一套高效的 iOS 面试题](https://juejin.im/post/5e397ccaf265da570b3f1b02) 31 | 32 | 另外,也感谢经典的[《招聘一个靠谱的 iOS》](https://github.com/ChenYilong/iOSInterviewQuestions)仓库带来的面试题整理启发。 33 | 34 | ## Contributors ✨ 35 | 36 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |

Gua

🖋

邓超界_dengChaoJie

🖋

Xi Lin

🖋

0x1306a94

🖋

YuriTT

🖋

XuYanCi @许还真

🖋

WhoJave

🖋
52 | 53 | 54 | 55 | 56 | 57 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! 58 | 59 | ## License 60 | 61 |

本作品采用 知识署名-非商业性使用-禁止演绎 (BY-NC-ND) 4.0 国际许可协议 进行许可。

62 | 63 | 64 | -------------------------------------------------------------------------------- /_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 序章 3 | type: docs 4 | --- 5 | 6 | ## 为什么会整理这套面试题? 7 | 8 | 其实是在公众号群里,各路朋友的呼声。毕竟关注技术的多数人是为了找到一个好工作,能够进心仪的大厂。所以希望制作一个面试题的词条收集,让大家一起参与编辑。 9 | 10 | 很多知识的答案是不断的讨论才能得出结论,且这些结论其实都是具有时效性的,例如 Apple 的 Runtime 特性、Swift 各种语法的优雅写法等,前者会随着 Runtime 仓库的版本迭代而变化,后者则会随着 Swift 语言的版本更替而改变。 11 | 12 | ## 如何参与面试题整理? 13 | 14 | 可以直接向内容仓库 [interval-content](https://github.com/idevqa/interval-content) 提 Pull Request 进行修改编辑申请。另外一个简单的方法,在每个词条问题页面中的左下角位置,都会有 `Edit this page` 的按钮,会直接打开 GitHub 编辑页面。如此可以快速发起 PR,当 @冬瓜 或者其他管理员 Review 通过后,方可合入词条。 15 | 16 | ## 适用人群 17 | 18 | iOS 方向求职应届生以及考虑机会的 iOS 工程师。 19 | 20 | ## 特别感谢 21 | 22 | 感谢以下题目来源: 23 | 24 | * [阿里、字节:一套高效的 iOS 面试题](https://juejin.im/post/5e397ccaf265da570b3f1b02) 25 | 26 | 另外,也感谢经典的[《招聘一个靠谱的 iOS》](https://github.com/ChenYilong/iOSInterviewQuestions)仓库带来的面试题整理启发。 27 | 28 | ## 词条贡献者 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |

Gua

🖋

邓超界_dengChaoJie

🖋

Xi Lin

🖋

0x1306a94

🖋

YuriTT

🖋

XuYanCi @许还真

🖋

WhoJave

🖋
44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /docs/ch01/tc01/01.md: -------------------------------------------------------------------------------- 1 | ### 计算机网络 2 | 3 | #### TCP的握手过程?为什么进行三次握手,四次挥手 4 | 5 | ![参考图片](./011.jpg) 6 | 7 | [了解更多](https://baijiahao.baidu.com/s?id=1618114723935605183&wfr=spider&for=pc) 8 | 9 | 10 | #### HTTPS的握手过程 11 | 12 | - 建立服务器443端口连接 13 | - SSL握手:证书,随机密钥,加密算法 14 | - 发送加密请求 15 | - 发送加密响应 16 | - 关闭SSL 17 | - 关闭TCP 18 | 19 | ![参考图片](./012.jpg) 20 | 21 | #### 什么是中间人攻击?怎么预防? 22 | 23 | - 中间人把自己的公钥给到客户端,之后用自己的私钥解开客户端数据,再用后台的公钥加密数据,发给后台。这样中间人能拿到双端的数据。 24 | 一般禁止接入代理和在代码内比对证书。 25 | 26 | 27 | #### charles抓包过程?不使用charles,4G网络如何抓包 28 | 29 | - 运行charles,手机配置代理。如果是http协议,charles能看到所有的请求和返回数据。如果要看到https的数据,需要在手机上安装charles证书,并信任证书。 30 | - 4G网络,如果是安卓设备,用Packet Capture、tshark或者tcpdump。如果是iOS设备,用Fiddler、tcpdump和wireshark。 31 | 32 | #### TCP和UDP的区别 33 | 34 | - TCP是IP网络上面向连接的流, 保证所有发送的包能够按照正确的顺序到达目的地。这意味着发送端要接受ACK包,包自动重传,相对于UDP来说会引起额外延迟以及传输效率更低。TCP还有拥塞控制,流量控制,错误校验等其他机制。 35 | 36 | - UDP是无连接传输协议,面向数据报传输,只保证单个数据报的正确性。数据报到达目的地,有可能会乱序,丢包,或者根本到达不了。由于它没有ACK,所以它比TCP传输效率更高。一般用在实时通讯,相对于TCP连接的开销,虽然存在较小丢包率,但更加适合。 37 | 38 | - 在某些场合下,UDP用来广播包传输。这在例如DHCP协议有时候是最基本的,因为客户端并没有接收到IP地址(DHCP 协商协议目的),这时候是没有办法在没有IP地址的情况下建立起TCP连接的。 39 | 40 | #### TCP拥塞控制 41 | ![参考图片](./tcp_congestion.png) 42 | - 慢启动、当 CongWin低于Threshold, 发送端在慢启动阶段,窗口指数增长。 43 | - 加性增、当 CongWin高于Threshold, 发送端在拥塞避免阶段,窗口线性增长。 44 | - 乘性减、当接收到三个重复的ACK,Threshold设置为CongWin/2,CongWin设置为Threshold。 45 | - 重置、当超时发生的时候,Threshold设置为CongWin/2,CongWin设置为1MSS,重新跑1-3流程 46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/ch01/tc01/01/011.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idevqa/interval-content/850dd091e2f2b0e3e06a819e8ccddf2ca83c7cac/docs/ch01/tc01/01/011.jpg -------------------------------------------------------------------------------- /docs/ch01/tc01/01/012.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idevqa/interval-content/850dd091e2f2b0e3e06a819e8ccddf2ca83c7cac/docs/ch01/tc01/01/012.jpg -------------------------------------------------------------------------------- /docs/ch01/tc01/01/tcp_congestion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idevqa/interval-content/850dd091e2f2b0e3e06a819e8ccddf2ca83c7cac/docs/ch01/tc01/01/tcp_congestion.png -------------------------------------------------------------------------------- /docs/ch01/tc02/02.md: -------------------------------------------------------------------------------- 1 | ### 操作系统 2 | 3 | #### 进程和线程的区别 4 | 5 | - 根本区别:进程是操作系统资源分配的基本单位,线程是任务调度和执行的基本单位; 6 | - 在开销方面:每个进程都有独立的代码和数据空间,程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。 7 | - 所处环境:在操作系统中能同时运行多个进程;而在同一个进程中有多个线程同时执行,通过CPU调度,在每个时间片中只有一个线程执行 8 | - 内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存,线程所使用的资源来自其所属进程的资源,线程组之间只能共享资源。 9 | - 包含关系:没有线程的进程可以看做是单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线共同完成的;线程是进程的一部分,所以线程也被称为轻量级进程。 10 | 11 | 12 | #### 堆和栈区的区别?谁的占用内存空间大 13 | 14 | - 栈内存存储的是局部变量,而堆内存是实体; 15 | - 栈内存的更新速度高于堆内存; 16 | - 栈内存的生命周期一结束就会被释放,而堆内存会被垃圾回收机制不定时回收。 17 | - 堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。 18 | 19 | -------------------------------------------------------------------------------- /docs/ch01/tc03/03.md: -------------------------------------------------------------------------------- 1 | ### 数据安全 2 | 3 | #### 对称加密算法和非对称加密算法区别 4 | 5 | 对称加密算法,是用的一个秘钥,进行加密和解密。而非对称加密算法,用的是一对秘钥,包括公钥和私钥,一般用公钥加密,私钥解密。 6 | 7 | 8 | #### 常见的对称加密和非对称加密算法有哪些 9 | 10 | 对称加密有AES、3DES,非对称加密有RSA。 11 | 12 | 13 | #### MD5、Sha1、Sha256区别 14 | 15 | - MD5值长度是128位(16个字符)、SHA1值长度是160位(20个字符)、SHA256值长度是256位(32个字符)。 16 | - MD5,消息摘要算法,一种被广泛使用的密码散列函数,可以产生一个128位长的散列值(hash value),用于确保信息传输完整一致。 17 | - Sha1,安全哈希算法,主要适用于数字签名标准里面定义的数字签名算法。对于长度小于2^64位的消息,Sha1会产生一个160位长的消息摘要。 18 | - Sha256,哈希值表示大量数据的固定大小的唯一值。数据的少量更改会在哈希值中产生不可预知的大量更改。Sha256 算法的哈希值长度为 256 位。 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/ch01/tc04/04.md: -------------------------------------------------------------------------------- 1 | ### 苹果证书 2 | 3 | #### 苹果使用证书的目的是什么 4 | 5 | - 苹果使用证书,来签名APP,一是防止APP被篡改,二是防止没有苹果签名的APP安装到设备上。 6 | 7 | 8 | #### AppStore安装app时的认证流程 9 | 10 | 当安装时,苹果的认证流程是, 11 | 1. 苹果用设备系统的本地公钥,验证APP的MD5值的签名。 12 | 13 | 在上传时,苹果的操作流程是, 14 | 1. 苹果验证发布证书和 Provisioning Profile 15 | 2. 苹果用后台的私钥,给包重新签名 16 | 17 | 所以,原来的本地私钥签名就没有用了。苹果没有控制包的有效期,就不需要内置 embedded.mobileprovision 。当上传到AppStore后,就跟你的 证书 / Provisioning Profile 都没有关系了。无论它们是否过期或被废除,都不会影响 AppStore 上的安装包。 18 | 19 | 20 | #### 开发者怎么在debug模式下把app安装到设备呢 21 | 22 | 1. 苹果用设备系统的本地公钥,验证 embedded.mobileprovision 的签名,验证开发证书的签名是否正确。 23 | 2. 用开发证书的公钥验证APP签名,验证AppID是否对应得上,设备ID是否在ID列表上,权限开关是否跟APP里的Entitlements对应等。 24 | 25 | 26 | -------------------------------------------------------------------------------- /docs/ch04/tc01/4-1-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: iOS 事件响应链机制 3 | --- 4 | 5 | > 词条作者:[@冬瓜](https://github.com/Desgard) 6 | 7 | {{< hint info >}} 8 | 9 | 10 | ### 题目还原 11 | 12 | 1. 什么 iOS 的事件响应链机制? 13 | 2. 响应链有什么作用? 14 | 3. 事件传递流程是怎样的? 15 | 4. iOS 是如何找到第一响应者的? 16 | 17 | {{< /hint >}} 18 | 19 | ## 什么是 iOS 的事件响应链机制? 20 | 21 | iOS 的事件响应链(Responder Chain)就是**当 UI 收到某个信号的响应后这种控件间自上到下消息传递的链路**。其中最重要的就是**事件传递流程**以及**如何找到第一响应者**。 22 | 23 | ### 响应链的作用 24 | 25 | 可以使得一个触摸事件选择多个对象来处理,简单来说系统是通过 `hitTest:withEvent:` 方法找到此次触摸事件的响应视图,然后调用视图的 `touchesBegan:withEvent:` 方法来处理事件。 26 | 27 | ### 事件传递流程 28 | 29 | ### 找到第一响应者 30 | 31 | ## 响应链的作用 32 | 33 | ### 扩大响应范围 34 | 35 | ### 复杂页面事件统一处理 36 | 37 | -------------------------------------------------------------------------------- /docs/ch04/tc01/4-1-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 什么是离屏渲染 3 | --- 4 | 5 | {{< hint info >}} 6 | 7 | ### 题目还原 8 | 9 | 什么是离屏渲染? 10 | 11 | {{< /hint >}} 12 | 13 | * 当图层属性的混合体被指定为在未预合成之前不能直接在屏幕中绘制时,离屏渲染就被唤起了。离屏渲染并不意味着软件绘制,但是它意味着图层必须在被显示之前在一个屏幕外上下文中被渲染(不论CPU还是GPU) 14 | * 如果要在显示屏上显示内容,我们至少需要一块与屏幕像素数据量一样大的frame buffer,作为像素数据存储区域,而这也是GPU存储渲染结果的地方。如果有时因为面临一些限制,无法把渲染结果直接写入frame buffer,而是先暂存在另外的内存区域,之后再写入frame buffer,那么这个过程被称之为离屏渲染 15 | 16 | ![参考图片](../412/1.png) 17 | 18 | ### 参考链接 19 | 1. https://github.com/seedante/iOS-Note/wiki/Mastering-Offscreen-Render 20 | 21 | 2. 推荐一本书 22 | 23 | -------------------------------------------------------------------------------- /docs/ch04/tc01/4-1-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: UI 的刷新原理 3 | --- 4 | 5 | {{< hint info >}} 6 | 7 | ### 题目还原 8 | 9 | 什么是离屏渲染? 10 | 11 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch04/tc01/4-1-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: UIView 和 CALayer 3 | --- 4 | 5 | {{< hint info >}} 6 | 7 | ### 题目还原 8 | 9 | `UIView` 和 `CALayer` 的区别是什么? 10 | 11 | {{< /hint >}} 12 | 13 | 简单来说,UIView 是对 CALayer 的一个封装。CALayer 负责显示内容contents,UIView 为其提供内容,以及负责处理触摸等事件,参与响应链。 14 | 15 | ![参考图片](../414/1.png) 16 | 17 | ### 参考链接: 18 | https://github.com/seedante/iOS-Note/wiki/Mastering-Offscreen-Render 19 | -------------------------------------------------------------------------------- /docs/ch04/tc01/4-1-5.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: layoutsubviews 和 drawrect 3 | --- 4 | 5 | {{< hint info >}} 6 | 7 | ### 题目还原 8 | 9 | `layoutsubviews` 和 `drawrect` 的作用是啥?其调用时机是怎样的? 10 | 11 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch04/tc01/4-1-6.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 什么是离屏渲染 3 | --- 4 | 5 | {{< hint info >}} 6 | 7 | ### 题目还原 8 | 9 | 什么是离屏渲染? 10 | 11 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch04/tc01/412/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idevqa/interval-content/850dd091e2f2b0e3e06a819e8ccddf2ca83c7cac/docs/ch04/tc01/412/1.png -------------------------------------------------------------------------------- /docs/ch04/tc01/414/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idevqa/interval-content/850dd091e2f2b0e3e06a819e8ccddf2ca83c7cac/docs/ch04/tc01/414/1.png -------------------------------------------------------------------------------- /docs/ch04/tc02/4-2-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: AutoLayout 原理与性能 3 | --- 4 | 5 | {{< hint info >}} 6 | 7 | ### 题目还原 8 | 9 | AutoLayout 原理是怎样的?其性能如何? 10 | 11 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch04/tc03/4-3-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 图片解码时机与优化 3 | --- 4 | 5 | {{< hint info >}} 6 | 7 | ### 题目还原 8 | 9 | 图片是什么时候解码的?如何优化? 10 | 11 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch04/tc03/4-3-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 多个相同的图片会重复加载吗? 3 | --- 4 | 5 | {{< hint info >}} 6 | 7 | ### 题目还原 8 | 9 | 多个相同的图片会重复加载吗? 10 | 11 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch04/tc03/4-3-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: imageName 和 imageWithContentsOfFile 3 | --- 4 | 5 | {{< hint info >}} 6 | 7 | ### 题目还原 8 | 9 | `imageName` 和 `imageWithContentsOfFile` 的作用是什么?其区别是? 10 | 11 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch05/tc01/5-1-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 线程 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **iOS 开发中有多少类型的线程?** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch05/tc01/5-1-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 同步 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **iOS 中如何实现同步?** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch05/tc01/5-1-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 锁 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **有哪些类型的线程锁,分别介绍下作用和使用场景** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch05/tc01/5-1-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 死锁 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **什么情况下会发生死锁?** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch05/tc02/5-2-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: GCD 队列 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **GCD 有哪些队列,默认提供哪些队列** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch05/tc02/5-2-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: GCD 线程与队列关系 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **说出 GCD 线程与队列关系** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch05/tc02/5-2-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: GCD API 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **列出 GCD 的一些常用 api** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch05/tc02/5-2-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: dispatch_once 实现原理 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **介绍下 `dispatch_once` 实现原理** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch05/tc03/5-3-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: NSOperationQueue 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **介绍下 `NSOperationQueue`, `maxConcurrentOperationCount` 的默认值是多少?** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch05/tc03/5-3-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: NSTimer, CADisplayLink, dispatch_source_t 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **比较 `NSTimer`, `CADisplayLink`, `dispatch_source_t` 的优劣** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc01/6-1-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Runtime 的内存模型 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **介绍下 Runtime 的内存模型(isa、对象、类、metaclass、结构体的存储信息等)** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc01/6-1-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: metaclass 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **介绍下 `metaclass` 是什么,作用是什么** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc01/6-1-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: class_copyIvarList & class_copyPropertyList有什么区别 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **`class_copyIvarList` & `class_copyPropertyList`有什么区别** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc01/6-1-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: class_rw_t 和 class_ro_t 有什么区别 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **`class_rw_t` 和 `class_ro_t` 有什么区别** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc01/6-1-5.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: category 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **介绍下`category`是什么,是如何被加载的。** 9 | 10 | **说说两个`category`的`load`方法的加载顺序,两个`category`的同名方法的加载顺序。** 11 | 12 | **`category` & `extension`的区别,是否能给`NSObject`添加`Extension`** 13 | {{< /hint >}} 14 | -------------------------------------------------------------------------------- /docs/ch06/tc01/6-1-6.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 消息转发 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **什么是消息转发,消息转发机制和其他语言的消息机制优劣对比** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc01/6-1-7.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 方法调用 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **在方法调用的时候,`方法查询-> 动态解析-> 消息转发`之前做了什么** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc01/6-1-8.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: IMP, SEL, Method 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **介绍下`IMP`, `SEL`, `Method`的区别和使用场景** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc01/6-1-9.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: load & initialize 3 | --- 4 | 5 | > 词条作者:[@0x1306a94](https://github.com/0x1306a94) 6 | 7 | {{< hint info >}} 8 | ### 题目还原 9 | 10 | **`load`、`initialize`方法的区别什么?在继承关系中他们有什么区别** 11 | {{< /hint >}} 12 | 13 | ### load 14 | > [Apple 官方文档介绍](https://developer.apple.com/documentation/objectivec/nsobject/1418815-load?preferredLanguage=occ) 15 | 16 | * 1. 每个`Class`、`Category`的 `+load`,在程序运行过程中只调用一次`(初始化Runtime时自动调用)` 17 | * 2. 先调用`Class`的`+load`,按照编译先后顺序调用`(先编译,先调用,调用子类的+load之前会先调用父类的+load)` 18 | * 3. 再调用`Category`的`+load`, 按照编译先后顺序调用`(先编译,先调用)` 19 | * 4. `+load`方法是根据方法地址直接调用,并不是经过`objc_msgSend`函数调用 20 | 21 | > 接下来通过源码来验证上面结论 22 | > 本文基于 `objc4-756.2.tar.gz` 源码分析, 具体源码文件为 `objc-runtime-new.mm` 23 | 24 | * 首先当你在手机上点击一个应用时,最终会由`dyld`将对应应用的可执行文件载入内存,然后进行一些初始化工作,其中会调用`_objc_init`, 这一流程可以通过添加一个`_objc_init`的符号断点,当断点断下时,可以通过`lldb`调试器输入`bt`查看详细的调用栈 25 | 26 | ```c 27 | void _objc_init(void) 28 | { 29 | static bool initialized = false; 30 | if (initialized) return; 31 | initialized = true; 32 | 33 | // fixme defer initialization until an objc-using image is found? 34 | environ_init(); 35 | tls_init(); 36 | static_init(); 37 | lock_init(); 38 | exception_init(); 39 | 40 | // _objc_init->map_images->map_images_nolock->_read_images->realizeClass 41 | _dyld_objc_notify_register(&map_images, load_images, unmap_image); 42 | } 43 | ``` 44 | * 在`_objc_init`中注册`dyld`回调,接下来主要关注`load_images`回调函数, `load_images`函数所做的事刚好验证了上面说的第一点 45 | 46 | ```c 47 | void load_images(const char *path __unused, const struct mach_header *mh) 48 | { 49 | // 检查有没有load 需要调用 50 | // 通过检查 mach-o 中 __objc_nlclslist 和 __objc_nlcatlist 段数据 51 | if (!hasLoadMethods((const headerType *)mh)) return; 52 | 53 | recursive_mutex_locker_t lock(loadMethodLock); 54 | 55 | // 准备所有load 56 | { 57 | mutex_locker_t lock2(runtimeLock); 58 | prepare_load_methods((const headerType *)mh); 59 | } 60 | 61 | // 调用所有load 62 | call_load_methods(); 63 | } 64 | ``` 65 | * 准备好所有`load`方法,先查找所有`Class`的`load`,然后是`Category`的`load` 这一步由`prepare_load_methods`函数完成 66 | 67 | ```c 68 | void prepare_load_methods(const headerType *mhdr) 69 | { 70 | size_t count, i; 71 | 72 | runtimeLock.assertLocked(); 73 | // 从 mach-o __objc_nlclslist 段中取出 所有 classref_t 数据 74 | classref_t *classlist = 75 | _getObjc2NonlazyClassList(mhdr, &count); 76 | for (i = 0; i < count; i++) { 77 | schedule_class_load(remapClass(classlist[i])); 78 | } 79 | 80 | // 从 mach-o __objc_nlcatlist 段中取出 所有 category_t 数据 81 | category_t **categorylist = _getObjc2NonlazyCategoryList(mhdr, &count); 82 | for (i = 0; i < count; i++) { 83 | category_t *cat = categorylist[i]; 84 | Class cls = remapClass(cat->cls); 85 | if (!cls) continue; // category for ignored weak-linked class 86 | realizeClass(cls); 87 | assert(cls->ISA()->isRealized()); 88 | add_category_to_loadable_list(cat); 89 | } 90 | } 91 | ``` 92 | 93 | ```c 94 | static void schedule_class_load(Class cls) 95 | { 96 | if (!cls) return; 97 | assert(cls->isRealized()); // _read_images should realize 98 | 99 | if (cls->data()->flags & RW_LOADED) return; 100 | 101 | // 首先处理了传入的cls 的superclas 102 | // 这一步验证了 上面所说第二点 (调用子类的+load之前会先调用父类的+load) 103 | schedule_class_load(cls->superclass); 104 | 105 | add_class_to_loadable_list(cls); 106 | cls->setInfo(RW_LOADED); 107 | } 108 | ``` 109 | 110 | ```c 111 | /*********************************************************************** 112 | * add_class_to_loadable_list 113 | * Class cls has just become connected. Schedule it for +load if 114 | * it implements a +load method. 115 | **********************************************************************/ 116 | void add_class_to_loadable_list(Class cls) 117 | { 118 | IMP method; 119 | 120 | loadMethodLock.assertLocked(); 121 | // 通过遍历 class_ro_t 中的 baseMethodList 122 | // 判断其每一个 method_t 中的 name 是否和 "load" 相等 123 | method = cls->getLoadMethod(); 124 | if (!method) return; // Don't bother if cls has no +load method 125 | 126 | if (PrintLoading) { 127 | _objc_inform("LOAD: class '%s' scheduled for +load", 128 | cls->nameForLogging()); 129 | } 130 | 131 | if (loadable_classes_used == loadable_classes_allocated) { 132 | loadable_classes_allocated = loadable_classes_allocated*2 + 16; 133 | loadable_classes = (struct loadable_class *) 134 | realloc(loadable_classes, 135 | loadable_classes_allocated * 136 | sizeof(struct loadable_class)); 137 | } 138 | // 如果cls 有实现 +load 则添加到 loadable_classes 变量中 139 | loadable_classes[loadable_classes_used].cls = cls; 140 | loadable_classes[loadable_classes_used].method = method; 141 | loadable_classes_used++; 142 | } 143 | ``` 144 | 145 | ```c 146 | /*********************************************************************** 147 | * add_category_to_loadable_list 148 | * Category cat's parent class exists and the category has been attached 149 | * to its class. Schedule this category for +load after its parent class 150 | * becomes connected and has its own +load method called. 151 | **********************************************************************/ 152 | void add_category_to_loadable_list(Category cat) 153 | { 154 | IMP method; 155 | 156 | loadMethodLock.assertLocked(); 157 | // 通过遍历 Category 中的 classMethods 158 | // 判断其每一个 method_t 中的 name 是否和 "load" 相等 159 | method = _category_getLoadMethod(cat); 160 | 161 | // Don't bother if cat has no +load method 162 | if (!method) return; 163 | 164 | if (PrintLoading) { 165 | _objc_inform("LOAD: category '%s(%s)' scheduled for +load", 166 | _category_getClassName(cat), _category_getName(cat)); 167 | } 168 | 169 | if (loadable_categories_used == loadable_categories_allocated) { 170 | loadable_categories_allocated = loadable_categories_allocated*2 + 16; 171 | loadable_categories = (struct loadable_category *) 172 | realloc(loadable_categories, 173 | loadable_categories_allocated * 174 | sizeof(struct loadable_category)); 175 | } 176 | 177 | // 如果 Category 有实现 +load 则添加到 loadable_categories 变量中 178 | loadable_categories[loadable_categories_used].cat = cat; 179 | loadable_categories[loadable_categories_used].method = method; 180 | loadable_categories_used++; 181 | } 182 | ``` 183 | * 调用`+load` 184 | 185 | ```c 186 | void call_load_methods(void) 187 | { 188 | static bool loading = NO; 189 | bool more_categories; 190 | 191 | loadMethodLock.assertLocked(); 192 | 193 | // Re-entrant calls do nothing; the outermost call will finish the job. 194 | if (loading) return; 195 | loading = YES; 196 | 197 | void *pool = objc_autoreleasePoolPush(); 198 | 199 | do { 200 | // 1. 调用Class 的 +load 201 | while (loadable_classes_used > 0) { 202 | call_class_loads(); 203 | } 204 | 205 | // 2. 调用 Category 的 +load 206 | more_categories = call_category_loads(); 207 | 208 | } while (loadable_classes_used > 0 || more_categories); 209 | 210 | objc_autoreleasePoolPop(pool); 211 | 212 | loading = NO; 213 | } 214 | ``` 215 | 216 | ```c 217 | // 调用 Class +load 218 | static void call_class_loads(void) 219 | { 220 | int i; 221 | 222 | // Detach current loadable list. 223 | struct loadable_class *classes = loadable_classes; 224 | int used = loadable_classes_used; 225 | loadable_classes = nil; 226 | loadable_classes_allocated = 0; 227 | loadable_classes_used = 0; 228 | 229 | // Call all +loads for the detached list. 230 | for (i = 0; i < used; i++) { 231 | Class cls = classes[i].cls; 232 | load_method_t load_method = (load_method_t)classes[i].method; 233 | if (!cls) continue; 234 | 235 | if (PrintLoading) { 236 | _objc_inform("LOAD: +[%s load]\n", cls->nameForLogging()); 237 | } 238 | // 直接调用, 不通过 objc_msgSend 调用 239 | (*load_method)(cls, SEL_load); 240 | } 241 | 242 | // Destroy the detached list. 243 | if (classes) free(classes); 244 | } 245 | 246 | // 调用 Category +load 247 | static bool call_category_loads(void) 248 | { 249 | int i, shift; 250 | bool new_categories_added = NO; 251 | 252 | // Detach current loadable list. 253 | struct loadable_category *cats = loadable_categories; 254 | int used = loadable_categories_used; 255 | int allocated = loadable_categories_allocated; 256 | loadable_categories = nil; 257 | loadable_categories_allocated = 0; 258 | loadable_categories_used = 0; 259 | 260 | // Call all +loads for the detached list. 261 | for (i = 0; i < used; i++) { 262 | Category cat = cats[i].cat; 263 | load_method_t load_method = (load_method_t)cats[i].method; 264 | Class cls; 265 | if (!cat) continue; 266 | 267 | cls = _category_getClass(cat); 268 | if (cls && cls->isLoadable()) { 269 | if (PrintLoading) { 270 | _objc_inform("LOAD: +[%s(%s) load]\n", 271 | cls->nameForLogging(), 272 | _category_getName(cat)); 273 | } 274 | // 直接调用, 不通过 objc_msgSend 调用 275 | (*load_method)(cls, SEL_load); 276 | cats[i].cat = nil; 277 | } 278 | } 279 | 280 | ...... 281 | return new_categories_added; 282 | } 283 | ``` 284 | 285 | ### initialize 286 | > [Apple 官方文档介绍](https://developer.apple.com/reference/objectivec/nsobject/1418639-initialize?language=objc) 287 | 288 | * 1. `+initialize`方法会在类第一次接收到消息时调用 289 | * 2. 先调用`父类的+initialize`,再调用`子类的+initialize` (先初始化父类,再初始化子类,每个类只会初始化1次) 290 | 291 | > 源码分析 292 | 293 | * 我们都知道 `OC` 中的方法调用最终都会转化为 `objc_msgSend` 调用, 在`objc_msgSend`的执行过程中会来到`lookUpImpOrForward`函数中,而`+initialize`的调用就是在`lookUpImpOrForward`函数中触发 294 | 295 | ```c 296 | IMP lookUpImpOrForward(Class cls, SEL sel, id inst, 297 | bool initialize, bool cache, bool resolver) 298 | { 299 | .... 300 | 301 | // 检查 cls 是否已经执行过 +initialize 302 | if (initialize && !cls->isInitialized()) { 303 | runtimeLock.unlock(); 304 | // 如果没有则执行 +initialize 305 | _class_initialize (_class_getNonMetaClass(cls, inst)); 306 | runtimeLock.lock(); 307 | } 308 | 309 | ..... 310 | 311 | return imp; 312 | } 313 | 314 | 315 | void _class_initialize(Class cls) 316 | { 317 | 318 | // 如果父类还没有执行过,则先执行 父类的 319 | supercls = cls->superclass; 320 | if (supercls && !supercls->isInitialized()) { 321 | _class_initialize(supercls); 322 | } 323 | 324 | callInitialize(cls); 325 | 326 | ..... 327 | } 328 | 329 | void callInitialize(Class cls) 330 | { 331 | // 调用 +initialize 332 | ((void(*)(Class, SEL))objc_msgSend)(cls, SEL_initialize); 333 | asm(""); 334 | } 335 | ``` 336 | 337 | ### loda方法与initialize方法的区别 338 | 339 | * `+initialize`和`+load`的很大区别是,`+initialize`是通过`objc_msgSend`进行调用的,所以有以下特点 340 | * 如果`子类没有实现+initialize`,会调用`父类的+initialize` 341 | * 如果`分类实现了+initialize`,就`覆盖类本身的+initialize调用` 342 | * `+load`是直接通过函数地址进行调用,并不通过`objc_msgSend`调用 343 | * 手动调用`+load`最终会转化为`objc_msgSend`调用 344 | * 如果类和分类没有实现`+load`,则不会调用 345 | 346 | -------------------------------------------------------------------------------- /docs/ch06/tc02/6-2-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: weak 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **`weak` 是如何实现的? `SideTable` 的结构是什么样的?** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc02/6-2-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 关联对象 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **关联对象是如何实现的,其内存管理如何进行** 9 | 10 | {{< /hint >}} 11 | -------------------------------------------------------------------------------- /docs/ch06/tc02/6-2-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Autoreleasepool 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **介绍下 `Autoreleasepool` 的原理,及其使用的数据结构** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc02/6-2-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ARC 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **介绍下 `ARC` 的实现原理。它对 `retain` & `release` 做了哪些优化?哪些情况会造成内存泄漏?** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc03/6-3-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Method Swizzle 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **介绍下 `Method Swizzle` 的原理与使用注意事项** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc03/6-3-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 属性修饰符 `atomic` 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **属性修饰符 `atomic` 的内部实现是怎么样的?能保证线程安全吗?** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc03/6-3-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: iOS 的内省方法 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **iOS 的内省方法有哪些?内部实现原理是什么?** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch06/tc03/6-3-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: class, objc_getClass, object_getclass 3 | --- 4 | 5 | > 词条作者:[@0x1306a94](https://github.com/0x1306a94) 6 | 7 | {{< hint info >}} 8 | ### 题目还原 9 | 10 | **`class`、`objc_getClass`、`object_getclass` 这几个方法的区别是什么?** 11 | {{< /hint >}} 12 | 13 | #### Class objc_getClass(const char *aClassName) 14 | * 传入C语言字符串形式类名,底层从一个`NXMapTable`的全局`gdb_objc_realized_classes`中查找对应的类对象 15 | 16 | ```c 17 | // 调用路径 18 | objc_getClass ~> look_up_class ~> getClass ~> getClass_impl 19 | 20 | // This is a misnomer: gdb_objc_realized_classes is actually a list of 21 | // named classes not in the dyld shared cache, whether realized or not. 22 | NXMapTable *gdb_objc_realized_classes; // exported for debuggers in objc-gdb.h 23 | 24 | static Class getClass_impl(const char *name) 25 | { 26 | runtimeLock.assertLocked(); 27 | 28 | // allocated in _read_images 29 | assert(gdb_objc_realized_classes); 30 | 31 | // Try runtime-allocated table 32 | Class result = (Class)NXMapGet(gdb_objc_realized_classes, name); 33 | if (result) return result; 34 | 35 | // Try table from dyld shared cache 36 | return getPreoptimizedClass(name); 37 | } 38 | ``` 39 | 40 | #### Class object_getClass(id obj) 41 | - 根据传入的obj, 获取obj的isa 42 | - 传入的obj可能是instance对象, class对象, meta-class对象 43 | - 如果传入的是instance对象,则返回class对象 44 | - 如果传入的是class对象,则返回meta-class对象 45 | - 如果传入的是meta-class对象,则返回NSObject(基类)的meta-class对象 46 | 47 | ```c 48 | /*********************************************************************** 49 | * object_getClass. 50 | * Locking: None. If you add locking, tell gdb (rdar://7516456). 51 | **********************************************************************/ 52 | Class object_getClass(id obj) 53 | { 54 | if (obj) return obj->getIsa(); 55 | else return Nil; 56 | } 57 | ``` 58 | 59 | #### -(Class)class +(Class)class 60 | - 返回类对象 61 | 62 | ```c 63 | + (Class)class { 64 | return self; 65 | } 66 | 67 | - (Class)class { 68 | return object_getClass(self); 69 | } 70 | ``` 71 | 72 | -------------------------------------------------------------------------------- /docs/ch07/tc01/7-1-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Runloop 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **app如何接收到触摸事件的** 9 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch07/tc02/7-1-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Runloop 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **为什么只有主线程的runloop是开启的** 9 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch07/tc03/7-1-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Runloop 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **为什么只在主线程刷新UI** 9 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch07/tc04/7-1-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Runloop 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **PerformSelector和runloop的关系** 9 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch07/tc05/7-1-5.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Runloop 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **如何使线程保活** 9 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch07/tc06/7-2-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: KVO 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **实现原理?** 9 | **如何手动关闭kvo?** 10 | **通过KVC修改属性会触发KVO么?** 11 | **哪些情况下使用kvo会崩溃,怎么防护崩溃?** 12 | **kvo的优缺点?** 13 | {{< /hint >}} -------------------------------------------------------------------------------- /docs/ch08/tc01/8-1-1.md: -------------------------------------------------------------------------------- 1 | 2 | ```c 3 | //block的内部实现及结构体 4 | struct Block_literal_1 { 5 | void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock 6 | int flags; 7 | int reserved; 8 | void (*invoke)(void *, ...); 9 | struct Block_descriptor_1 { 10 | unsigned long int reserved; // NULL 11 | unsigned long int size; // sizeof(struct Block_literal_1) 12 | // optional helper functions 13 | void (*copy_helper)(void *dst, void *src); // IFF (1<<25) 14 | void (*dispose_helper)(void *src); // IFF (1<<25) 15 | // required ABI.2010.3.16 16 | const char *signature; // IFF (1<<30) 17 | } *descriptor; 18 | // imported variables 19 | }; 20 | ``` 21 | 验证: 22 | xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC文件 -o CPP文件 23 | 24 | ```objective-c 25 | //OC文件 26 | int main(int argc, char * argv[]) { 27 | NSString * appDelegateClassName; 28 | @autoreleasepool { 29 | // Setup code that might create autoreleased objects goes here. 30 | void(^block)(void) = ^(){ 31 | NSLog(@"Test block"); 32 | }; 33 | block(); 34 | } 35 | return UIApplicationMain(argc, argv, nil, appDelegateClassName); 36 | } 37 | ``` 38 | ```C++ 39 | //CPP文件 40 | ... 41 | //block的结构体实现 42 | struct __block_impl { 43 | void *isa; 44 | int Flags; 45 | int Reserved; 46 | void *FuncPtr; 47 | }; 48 | 49 | struct __main_block_impl_0 { 50 | struct __block_impl impl; 51 | struct __main_block_desc_0* Desc; 52 | __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) { 53 | //根据isa可判断block的类型 54 | impl.isa = &_NSConcreteStackBlock; 55 | impl.Flags = flags; 56 | impl.FuncPtr = fp; 57 | Desc = desc; 58 | } 59 | }; 60 | 61 | //包含block内部代码块的函数 62 | static void __main_block_func_0(struct __main_block_impl_0 *__cself) { 63 | 64 | NSLog((NSString *)&__NSConstantStringImpl__var_folders_ts_hp0jhb4d1ss_910d_xcbb_g40000gn_T_main_fc9641_mi_0); 65 | } 66 | 67 | //block的描述 68 | static struct __main_block_desc_0 { 69 | size_t reserved; 70 | size_t Block_size; 71 | } __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)}; 72 | 73 | int main(int argc, char * argv[]) { 74 | NSString * appDelegateClassName; 75 | /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 76 | 77 | void(*block)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA)); 78 | ((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block); 79 | } 80 | return UIApplicationMain(argc, argv, __null, appDelegateClassName); 81 | } 82 | ... 83 | ``` 84 | 使用clang rewrite的cpp代码中可以看出block的内部实现,block调用时实际上是调用FuncPtr(指向包含block代码块函数的指针) 85 | 参考: 86 | [Block Implementation Specification](https://clang.llvm.org/docs/Block-ABI-Apple.html) 87 | -------------------------------------------------------------------------------- /docs/ch08/tc01/8-1-2.md: -------------------------------------------------------------------------------- 1 | #### block是类吗,有哪些类型 2 | 3 | block本质是OC对象(Blocks are Objective-C objects),内部含有isa指针. 4 | 5 | #### block的类型 6 | 7 | - __NSStackBlock__(_NSConcreteStackBlock) 8 | ``` 9 | 栈区 调用copy后 会将栈中的block调用到堆上 类型转变为__NSMallocBlock__ 10 | ``` 11 | - __NSGlobalBlock__(_NSConcreteGlobalBlock) 12 | ``` 13 | 数据区 调用copy后 什么都不做 14 | ``` 15 | - __NSMallocBlock__(_NSConcreteMallocBlock) 16 | ``` 17 | 堆区 调用copy后 引用计数增加 18 | ``` 19 | 20 | ```C 21 | //block底层结构形式 22 | struct Block_literal_1 { 23 | void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock 24 | int flags; 25 | int reserved; 26 | void (*invoke)(void *, ...); 27 | struct Block_descriptor_1 { 28 | unsigned long int reserved; // NULL 29 | unsigned long int size; // sizeof(struct Block_literal_1) 30 | // optional helper functions 31 | void (*copy_helper)(void *dst, void *src); // IFF (1<<25) 32 | void (*dispose_helper)(void *src); // IFF (1<<25) 33 | // required ABI.2010.3.16 34 | const char *signature; // IFF (1<<30) 35 | } *descriptor; 36 | // imported variables 37 | }; 38 | ``` 39 | 40 | 参考: 41 | - [Working with block](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html#//apple_ref/doc/uid/TP40011210-CH8-SW1) 42 | - [Block Implementation Specification](https://clang.llvm.org/docs/Block-ABI-Apple.html) 43 | -------------------------------------------------------------------------------- /docs/ch08/tc01/8-1-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: block变量 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **一个int变量被 __block 修饰与否的区别?block的变量截获** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch08/tc01/8-1-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: block变量 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **block在修改NSMutableArray,需不需要添加__block** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch08/tc01/8-1-5.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: block内存管理 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **block怎么进行内存管理的** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch08/tc01/8-1-6.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: block修饰词 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **block可以用strong修饰吗** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch08/tc01/8-1-7.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 循环引用 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **解决循环引用时为什么要用__strong、__weak修饰** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch08/tc01/8-1-8.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: block的copy操作 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **block发生copy时机** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch08/tc01/8-1-9.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: block,ARC,MRC 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **Block访问对象类型的auto变量时,在ARC和MRC下有什么区别** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch09/tc01/9-1-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 埋点 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **手动埋点、自动化埋点、可视化埋点** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch09/tc01/9-1-10.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: APP 架构 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **你的app架构是什么,有什么优缺点、为什么这么做、怎么改进** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch09/tc01/9-1-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: MVC, MVP, MVVM 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **介绍下 `MVC`, `MVP`, `MVVM`** 9 | {{< /hint >}} 10 | 11 | #### MV(X) 12 | 13 | * Models - 存放业务数据或者处理数据相关的数据访问层。例如 ‘Person’ 或者 ‘PersonDataProvider’ 类。 14 | * Views - 存放展示层(GUI),在iOS中,前缀是UI的。 15 | * Controller/Presenter/ViewModel  - 模型和视图之间的胶水或者媒介,一般来说,通过用户在视图上的事件触发改变模型,以及模型的更新反映到用户视图上。 16 | 17 | #### MVC 18 | ![参考图片](../912/1.png) 19 | * 分布 - View 和 Model 实际上是分离的,但是View和Controller却耦合太深。 20 | * 可测试性 - 因为耦合性太深,你只能测试你的Model。 21 | * 易用性 - 对比其他模式代码最少。 除此之外,开发者相对比较熟悉它,同时它也方便给那些经验不足的开发者维护。 22 | 23 | 24 | #### MVP 25 | ![参考图片](../912/2.png) 26 | * 分布 - 我们大部分责任都在分类 Presenter和Model,以及一个非常轻量的View。 27 | * 可测试性 - 非常棒,因为视图的轻量级别,我们可以很方便的测试大部分逻辑。 28 | * 易用性 - 代码量是MVC的双倍,同时,MVP的目的是非常清晰的。 29 | 30 | #### MVVM 31 | ![参考图片](../912/3.png) 32 | * 分布 - MVVM的View相对于MVP的View有着更多的责任。因为前者是通过设置绑定,从View Model中来更新状态,后者是将所有事件传递给Presenter,并不更新自身。 33 | * 可测性 - View Model与View没有任何联系,这个允许我们很方便的测试。View或许也是可以测试,但是因为依赖UIKit,我们往往会跳过它。 34 | * 易用性 - 代码量和我们之前的MVP模式例子大致相同,但是在实际应用中,你必须要从View传递所有事件给Presenter和手动更新View,MVVM显得更加精简,如果使用绑定的话。 35 | 36 | 37 | #### 参考链接 38 | https://medium.com/ios-os-x-development/ios-architecture-patterns-ecba4c38de52#.67bu0gn15 39 | -------------------------------------------------------------------------------- /docs/ch09/tc01/9-1-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 设计模式 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **列举常见的设计模式** 9 | {{< /hint >}} 10 | 11 | #### 什么是设计模式? 12 | 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。 13 | 14 | #### 什么是 GOF(四人帮,全拼 Gang of Four)? 15 | 在 1994 年,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人合著出版了一本名为 Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式 - 可复用的面向对象软件元素) 的书,该书首次提到了软件开发中设计模式的概念。四位作者合称 GOF(四人帮,全拼 Gang of Four)。他们所提出的设计模式主要是基于以下的面向对象设计原则。 16 | 17 | * 对接口编程而不是对实现编程。 18 | * 优先使用对象组合而不是继承。 19 | 20 | #### 设计原则 SOLID 21 | * 单一职责 - 一个类应该只有一个发生变化的原因 22 | * 开闭原则 - 一个软件实体应当对扩展开发,对修改关闭。 23 | * 里氏代换原则 - 一个软件实体如果使用的是一个基类的话,那么一定适用于其子类,而且它根本不能察觉出基类对象和子类对象的区别。 24 | * 接口隔离原则 - 使用多个专门的接口比使用单一的总接口要好。 25 | * 依赖倒转原则 - 要依赖与抽象,不要依赖于具体。 26 | * 迪米特法则 - 一个对象应当对其他对象有尽可能少的了解。 27 | * 组合、聚合复用原则 - 要尽量使用合成/聚合,尽量不要使用继承。 28 | 29 | #### 设计模式类型 30 | #### 创建型 31 | 在软件工程中,创建型模式是处理对象创建的设计模式,试图根据实际情况使用合适的方式创建对象。基本的对象创建方式可能会导致设计上的问题,或增加设计的复杂度。创建型模式通过以某种方式控制对象的创建来解决问题。 32 | 33 | * 简单工厂 34 | * 工厂 35 | * 抽象工程 36 | * 建造者 37 | * 模板 38 | * 单例 39 | 40 | #### 行为型 41 | 在软件工程中, 行为型模式为设计模式的一种类型,用来识别对象之间的常用交流模式并加以实现。如此,可在进行这些交流活动时增强弹性。 42 | 43 | * 适配者 44 | * 桥接 45 | * 组合 46 | * 装饰者 47 | * 外观 48 | * 享元 49 | * 代理 50 | 51 | #### 结构型 52 | 在软件工程中结构型模式是设计模式,借由一以贯之的方式来了解元件间的关系,以简化设计。 53 | 54 | * 责任链 55 | * 命令 56 | * 迭代者 57 | * 备忘 58 | * 观察者 59 | * 访问者 60 | * 策略 61 | * 状态 62 | * 模板方法 63 | 64 | #### 常见的设计模式 65 | 66 | * 单例模式 67 | * 工厂模式 68 | * 观察者模式 69 | * 响应链模式 70 | * 策略模式 71 | * 中间者模式 72 | * 装饰者模式 73 | 74 | #### 参考链接 75 | https://github.com/kamranahmedse/design-patterns-for-humans 76 | 77 | #### TIPS 78 | 还有一本书 <> 里面有说到Cocoa中使用了哪些设计模式,有兴趣可以看一下。 79 | 80 | 81 | -------------------------------------------------------------------------------- /docs/ch09/tc01/9-1-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 单例 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **介绍下单例模式及其弊端** 9 | {{< /hint >}} 10 | 11 | #### 单例模式 12 | 单例模式,也叫单子模式,是一种常用的软件设计模式,属于创建型模式的一种。在应用这个模式时,单例对象的类必须保证只有一个实例存在。 13 | 14 | 15 | #### 饿汉式单例类 16 | ![参考图片](../914/1.png) 17 | - 优点 - 简单方便。 18 | - 缺点 - 不管程序中是否使用到了单例对象,都会生成单例对象,并且由于静态对象是在类加载时就需要生成,会降低应用的启动速度。 19 | - 适用场景 - 类对象功能简单,占用内存较小,频繁使用。 20 | - 不适用 - 类对象功能复杂,占用内存大,适用概率较低 21 | 22 | #### 饱汉式单例类 23 | ![参考图片](../914/2.png) 24 | - 优点 - 单例对象的生成是应用需要使用单例对象时采取构造,可以提高应用的启动速度。 25 | - 缺点 - 不是线程安全的,如果多个线程同时调用getInstance方法,那么可能会生成多个单例对象。 26 | - 适用场景 - 单例对象功能复杂,占用内存大,对应用的启动速度有要求。 27 | - 不适用 - 多线程同时使用。 28 | 29 | 饿汉式单例类以及饱汉式单例类由于构造子是私有的,因此不可被继承,为了解决这个问题,出现了登记式单例类。 30 | 31 | 32 | #### 参考链接: 33 | https://baijiahao.baidu.com/s?id=1642521443436643881&wfr=spider&for=pc 34 | 35 | -------------------------------------------------------------------------------- /docs/ch09/tc01/9-1-5.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 路由 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **常见的路由方案,以及优缺点对比** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch09/tc01/9-1-6.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 稳定性 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **如果保证项目的稳定性** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch09/tc01/9-1-7.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 缓存 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **设计一个图片缓存框架** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch09/tc01/9-1-8.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: git diff 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **如何设计一个 `git diff`** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch09/tc01/9-1-9.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 线程池 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **设计一个线程池,画出你的架构图** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch09/tc01/912/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idevqa/interval-content/850dd091e2f2b0e3e06a819e8ccddf2ca83c7cac/docs/ch09/tc01/912/1.png -------------------------------------------------------------------------------- /docs/ch09/tc01/912/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idevqa/interval-content/850dd091e2f2b0e3e06a819e8ccddf2ca83c7cac/docs/ch09/tc01/912/2.png -------------------------------------------------------------------------------- /docs/ch09/tc01/912/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idevqa/interval-content/850dd091e2f2b0e3e06a819e8ccddf2ca83c7cac/docs/ch09/tc01/912/3.png -------------------------------------------------------------------------------- /docs/ch09/tc01/914/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idevqa/interval-content/850dd091e2f2b0e3e06a819e8ccddf2ca83c7cac/docs/ch09/tc01/914/1.png -------------------------------------------------------------------------------- /docs/ch09/tc01/914/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idevqa/interval-content/850dd091e2f2b0e3e06a819e8ccddf2ca83c7cac/docs/ch09/tc01/914/2.png -------------------------------------------------------------------------------- /docs/ch10/tc01/10-1-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 启动 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **如何做启动优化,如何监控** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch10/tc01/10-1-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 卡顿 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **如何做卡顿优化,如何监控** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch10/tc01/10-1-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 耗电 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **如何做耗电优化,如何监控** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /docs/ch10/tc01/10-1-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 网络 3 | --- 4 | 5 | {{< hint info >}} 6 | ### 题目还原 7 | 8 | **如何做网络优化,如何监控** 9 | {{< /hint >}} 10 | -------------------------------------------------------------------------------- /menu/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | headless: true 3 | category: menu 4 | --- 5 | 6 | - [序章]({{< relref "/" >}}) 7 | - 第一章 基础知识 8 | - [1.1 计算机网络]({{< relref "/docs/ch01/tc01/01" >}}) 9 | - [1.2 操作系统]({{< relref "/docs/ch01/tc02/02" >}}) 10 | - [1.3 数据安全]({{< relref "/docs/ch01/tc03/03" >}}) 11 | - [1.4 苹果证书]({{< relref "/docs/ch01/tc04/04" >}}) 12 | - 第二章 数据结构与算法 13 | - 第三章 语法特性 14 | - 第四章 UIKit 15 | - 4.1 基础 16 | - [什么是事件响应链]({{< relref "/docs/ch04/tc01/4-1-1" >}}) 17 | - [什么是离屏渲染]({{< relref "/docs/ch04/tc01/4-1-2" >}}) 18 | - [UI 的刷新原理]({{< relref "/docs/ch04/tc01/4-1-3" >}}) 19 | - [`UIView` 和 `CALayer`]({{< relref "/docs/ch04/tc01/4-1-4" >}}) 20 | - [`layoutsubviews`]({{< relref "/docs/ch04/tc01/4-1-5" >}}) 21 | - 4.2 布局方式 22 | - [AutoLayout 原理与性能]({{< relref "/docs/ch04/tc02/4-2-1" >}}) 23 | - 4.3 图片 24 | - [图片解码时机与优化]({{< relref "/docs/ch04/tc03/4-3-1" >}}) 25 | - [图片渲染优化]({{< relref "/docs/ch04/tc03/4-3-1" >}}) 26 | - [多个相同图片重复加载]({{< relref "/docs/ch04/tc03/4-3-2" >}}) 27 | - [imageName]({{< relref "/docs/ch04/tc03/4-3-3" >}}) 28 | - 第五章 多线程 29 | - 5.1 基础 30 | - [线程]({{< relref "/docs/ch05/tc01/5-1-1" >}}) 31 | - [同步]({{< relref "/docs/ch05/tc01/5-1-2" >}}) 32 | - [锁]({{< relref "/docs/ch05/tc01/5-1-3" >}}) 33 | - [死锁]({{< relref "/docs/ch05/tc01/5-1-4" >}}) 34 | - 5.2 GCD 35 | - [GCD 队列]({{< relref "/docs/ch05/tc02/5-2-1" >}}) 36 | - [GCD 线程与队列关系]({{< relref "/docs/ch05/tc02/5-2-2" >}}) 37 | - [GCD API]({{< relref "/docs/ch05/tc02/5-2-3" >}}) 38 | - [`dispatch_once` 实现原理]({{< relref "/docs/ch05/tc02/5-2-4" >}}) 39 | - 5.3 其他 40 | - [`NSOperationQueue`]({{< relref "/docs/ch05/tc03/5-3-1" >}}) 41 | - [`NSTimer`, `CADisplayLink`, `dispatch_source_t`]({{< relref "/docs/ch05/tc03/5-3-2" >}}) 42 | - 第六章 Runtime 43 | - 6.1 结构模型 44 | - [Runtime 的内存模型]({{< relref "/docs/ch06/tc01/6-1-1" >}}) 45 | - [`metaclass`]({{< relref "/docs/ch06/tc01/6-1-2" >}}) 46 | - [`class_copyIvarList`]({{< relref "/docs/ch06/tc01/6-1-3" >}}) 47 | - [`class_rw_t`]({{< relref "/docs/ch06/tc01/6-1-4" >}}) 48 | - [Category]({{< relref "/docs/ch06/tc01/6-1-5" >}}) 49 | - [消息转发]({{< relref "/docs/ch06/tc01/6-1-6" >}}) 50 | - [方法调用]({{< relref "/docs/ch06/tc01/6-1-7" >}}) 51 | - [`IMP`, `SEL` 和 `Method`]({{< relref "/docs/ch06/tc01/6-1-8" >}}) 52 | - [`load`, `initialize`]({{< relref "/docs/ch06/tc01/6-1-9" >}}) 53 | - 6.2 内存管理 54 | - [`weak` 弱引用]({{< relref "/docs/ch06/tc02/6-2-1" >}}) 55 | - [关联对象]({{< relref "/docs/ch06/tc02/6-2-2" >}}) 56 | - [Autoreleasepool]({{< relref "/docs/ch06/tc02/6-2-3" >}}) 57 | - [ARC 自动引用计数]({{< relref "/docs/ch06/tc02/6-2-4" >}}) 58 | - 6.3 59 | - [Method Swizzle]({{< relref "/docs/ch06/tc03/6-3-1" >}}) 60 | - [属性修饰符 `atomic`]({{< relref "/docs/ch06/tc03/6-3-2" >}}) 61 | - [iOS 的内省方法]({{< relref "/docs/ch06/tc03/6-3-3" >}}) 62 | - [`objc_getClass`]({{< relref "/docs/ch06/tc03/6-3-4" >}}) 63 | - 第七章 RunLoop和KVO 64 | - 7.1 RunLoop 65 | - [app如何接收到触摸事件的]({{< relref "/docs/ch07/tc01/7-1-1" >}}) 66 | - [为什么只有主线程的runloop是开启的]({{< relref "/docs/ch07/tc02/7-1-2" >}}) 67 | - [为什么只在主线程刷新UI]({{< relref "/docs/ch07/tc03/7-1-3" >}}) 68 | - [PerformSelector和runloop的关系]({{< relref "/docs/ch07/tc04/7-1-4" >}}) 69 | - [如何使线程保活]({{< relref "/docs/ch07/tc05/7-1-5" >}}) 70 | - [7.2 KVO]({{< relref "/docs/ch07/tc06/7-2-1" >}}) 71 | - 第八章 Block 72 | - [block的内部实现,结构体是什么样的]({{< relref "/docs/ch08/tc01/8-1-1" >}}) 73 | - [block是类吗,有哪些类型]({{< relref "/docs/ch08/tc01/8-1-2" >}}) 74 | - [一个int变量被 __block 修饰与否的区别?block的变量截获]({{< relref "/docs/ch08/tc01/8-1-3" >}}) 75 | - [block在修改NSMutableArray,需不需要添加__block]({{< relref "/docs/ch08/tc01/8-1-4" >}}) 76 | - [block怎么进行内存管理的]({{< relref "/docs/ch08/tc01/8-1-5" >}}) 77 | - [block可以用strong修饰吗]({{< relref "/docs/ch08/tc01/8-1-6" >}}) 78 | - [解决循环引用时为什么要用__strong、__weak修饰]({{< relref "/docs/ch08/tc01/8-1-7" >}}) 79 | - [block发生copy时机]({{< relref "/docs/ch08/tc01/8-1-8" >}}) 80 | - [Block访问对象类型的auto变量时,在ARC和MRC下有什么区别]({{< relref "/docs/ch08/tc01/8-1-9" >}}) 81 | - 第九章 工程架构 82 | - 9.1 架构设计 83 | - [埋点]({{< relref "/docs/ch09/tc01/9-1-1" >}}) 84 | - [`MVC`, `MVP`, `MVVM`]({{< relref "/docs/ch09/tc01/9-1-2" >}}) 85 | - [设计模式]({{< relref "/docs/ch09/tc01/9-1-3" >}}) 86 | - [单例]({{< relref "/docs/ch09/tc01/9-1-4" >}}) 87 | - [路由]({{< relref "/docs/ch09/tc01/9-1-5" >}}) 88 | - [稳定性]({{< relref "/docs/ch09/tc01/9-1-6" >}}) 89 | - [缓存]({{< relref "/docs/ch09/tc01/9-1-7" >}}) 90 | - [`git diff`]({{< relref "/docs/ch09/tc01/9-1-8" >}}) 91 | - [线程池]({{< relref "/docs/ch09/tc01/9-1-9" >}}) 92 | - [APP 架构]({{< relref "/docs/ch09/tc01/9-1-10" >}}) 93 | - 第十章 性能优化 94 | - 10.1 95 | - [启动]({{< relref "/docs/ch10/tc01/10-1-1" >}}) 96 | - [卡顿]({{< relref "/docs/ch10/tc01/10-1-2" >}}) 97 | - [耗电]({{< relref "/docs/ch10/tc01/10-1-3" >}}) 98 | - [网络]({{< relref "/docs/ch10/tc01/10-1-4" >}}) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "all-contributors-cli": "^6.14.0" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6": 6 | version "7.8.4" 7 | resolved "https://bnpm.byted.org/@babel/runtime/download/@babel/runtime-7.8.4.tgz#d79f5a2040f7caa24d53e563aad49cbc05581308" 8 | integrity sha1-159aIED3yqJNU+VjqtScvAVYEwg= 9 | dependencies: 10 | regenerator-runtime "^0.13.2" 11 | 12 | "@types/color-name@^1.1.1": 13 | version "1.1.1" 14 | resolved "https://bnpm.byted.org/@types/color-name/download/@types/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" 15 | integrity sha1-HBJhu+qhCoBVu8XYq4S3sq/IRqA= 16 | 17 | ajv@^6.5.5: 18 | version "6.12.0" 19 | resolved "https://bnpm.byted.org/ajv/download/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" 20 | integrity sha1-BtYLlth7hFSlrauobnhU2mKdtLc= 21 | dependencies: 22 | fast-deep-equal "^3.1.1" 23 | fast-json-stable-stringify "^2.0.0" 24 | json-schema-traverse "^0.4.1" 25 | uri-js "^4.2.2" 26 | 27 | all-contributors-cli@^6.14.0: 28 | version "6.14.0" 29 | resolved "https://bnpm.byted.org/all-contributors-cli/download/all-contributors-cli-6.14.0.tgz#9ecddabd9c1befef660f7589289b264db94bbbc8" 30 | integrity sha1-ns3avZwb7+9mD3WJKJsmTblLu8g= 31 | dependencies: 32 | "@babel/runtime" "^7.7.6" 33 | async "^3.0.1" 34 | chalk "^3.0.0" 35 | didyoumean "^1.2.1" 36 | inquirer "^7.0.4" 37 | json-fixer "^1.4.0" 38 | lodash "^4.11.2" 39 | pify "^5.0.0" 40 | request "^2.72.0" 41 | yargs "^15.0.1" 42 | 43 | ansi-escapes@^4.2.1: 44 | version "4.3.0" 45 | resolved "https://bnpm.byted.org/ansi-escapes/download/ansi-escapes-4.3.0.tgz#a4ce2b33d6b214b7950d8595c212f12ac9cc569d" 46 | integrity sha1-pM4rM9ayFLeVDYWVwhLxKsnMVp0= 47 | dependencies: 48 | type-fest "^0.8.1" 49 | 50 | ansi-regex@^4.1.0: 51 | version "4.1.0" 52 | resolved "https://bnpm.byted.org/ansi-regex/download/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" 53 | integrity sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc= 54 | 55 | ansi-regex@^5.0.0: 56 | version "5.0.0" 57 | resolved "https://bnpm.byted.org/ansi-regex/download/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" 58 | integrity sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U= 59 | 60 | ansi-styles@^3.2.1: 61 | version "3.2.1" 62 | resolved "https://bnpm.byted.org/ansi-styles/download/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 63 | integrity sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0= 64 | dependencies: 65 | color-convert "^1.9.0" 66 | 67 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 68 | version "4.2.1" 69 | resolved "https://bnpm.byted.org/ansi-styles/download/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" 70 | integrity sha1-kK51xCTQCNJiTFvynq0xd+v881k= 71 | dependencies: 72 | "@types/color-name" "^1.1.1" 73 | color-convert "^2.0.1" 74 | 75 | asn1@~0.2.3: 76 | version "0.2.4" 77 | resolved "https://bnpm.byted.org/asn1/download/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" 78 | integrity sha1-jSR136tVO7M+d7VOWeiAu4ziMTY= 79 | dependencies: 80 | safer-buffer "~2.1.0" 81 | 82 | assert-plus@1.0.0, assert-plus@^1.0.0: 83 | version "1.0.0" 84 | resolved "https://bnpm.byted.org/assert-plus/download/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" 85 | integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= 86 | 87 | async@^3.0.1: 88 | version "3.2.0" 89 | resolved "https://bnpm.byted.org/async/download/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" 90 | integrity sha1-s6JoXF67ZB094C0WEALGD8n4VyA= 91 | 92 | asynckit@^0.4.0: 93 | version "0.4.0" 94 | resolved "https://bnpm.byted.org/asynckit/download/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 95 | integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= 96 | 97 | aws-sign2@~0.7.0: 98 | version "0.7.0" 99 | resolved "https://bnpm.byted.org/aws-sign2/download/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" 100 | integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= 101 | 102 | aws4@^1.8.0: 103 | version "1.9.1" 104 | resolved "https://bnpm.byted.org/aws4/download/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" 105 | integrity sha1-fjPY99RJs/ZzzXLeuavcVS2+Uo4= 106 | 107 | bcrypt-pbkdf@^1.0.0: 108 | version "1.0.2" 109 | resolved "https://bnpm.byted.org/bcrypt-pbkdf/download/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" 110 | integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= 111 | dependencies: 112 | tweetnacl "^0.14.3" 113 | 114 | camelcase@^5.0.0: 115 | version "5.3.1" 116 | resolved "https://bnpm.byted.org/camelcase/download/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 117 | integrity sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA= 118 | 119 | caseless@~0.12.0: 120 | version "0.12.0" 121 | resolved "https://bnpm.byted.org/caseless/download/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" 122 | integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= 123 | 124 | chalk@^2.4.2: 125 | version "2.4.2" 126 | resolved "https://bnpm.byted.org/chalk/download/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 127 | integrity sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ= 128 | dependencies: 129 | ansi-styles "^3.2.1" 130 | escape-string-regexp "^1.0.5" 131 | supports-color "^5.3.0" 132 | 133 | chalk@^3.0.0: 134 | version "3.0.0" 135 | resolved "https://bnpm.byted.org/chalk/download/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" 136 | integrity sha1-P3PCv1JlkfV0zEksUeJFY0n4ROQ= 137 | dependencies: 138 | ansi-styles "^4.1.0" 139 | supports-color "^7.1.0" 140 | 141 | chardet@^0.7.0: 142 | version "0.7.0" 143 | resolved "https://bnpm.byted.org/chardet/download/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" 144 | integrity sha1-kAlISfCTfy7twkJdDSip5fDLrZ4= 145 | 146 | cli-cursor@^3.1.0: 147 | version "3.1.0" 148 | resolved "https://bnpm.byted.org/cli-cursor/download/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" 149 | integrity sha1-JkMFp65JDR0Dvwybp8kl0XU68wc= 150 | dependencies: 151 | restore-cursor "^3.1.0" 152 | 153 | cli-width@^2.0.0: 154 | version "2.2.0" 155 | resolved "https://bnpm.byted.org/cli-width/download/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" 156 | integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= 157 | 158 | cliui@^6.0.0: 159 | version "6.0.0" 160 | resolved "https://bnpm.byted.org/cliui/download/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" 161 | integrity sha1-UR1wLAxOQcoVbX0OlgIfI+EyJbE= 162 | dependencies: 163 | string-width "^4.2.0" 164 | strip-ansi "^6.0.0" 165 | wrap-ansi "^6.2.0" 166 | 167 | color-convert@^1.9.0: 168 | version "1.9.3" 169 | resolved "https://bnpm.byted.org/color-convert/download/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 170 | integrity sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg= 171 | dependencies: 172 | color-name "1.1.3" 173 | 174 | color-convert@^2.0.1: 175 | version "2.0.1" 176 | resolved "https://bnpm.byted.org/color-convert/download/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 177 | integrity sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM= 178 | dependencies: 179 | color-name "~1.1.4" 180 | 181 | color-name@1.1.3: 182 | version "1.1.3" 183 | resolved "https://bnpm.byted.org/color-name/download/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 184 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 185 | 186 | color-name@~1.1.4: 187 | version "1.1.4" 188 | resolved "https://bnpm.byted.org/color-name/download/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 189 | integrity sha1-wqCah6y95pVD3m9j+jmVyCbFNqI= 190 | 191 | combined-stream@^1.0.6, combined-stream@~1.0.6: 192 | version "1.0.8" 193 | resolved "https://bnpm.byted.org/combined-stream/download/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 194 | integrity sha1-w9RaizT9cwYxoRCoolIGgrMdWn8= 195 | dependencies: 196 | delayed-stream "~1.0.0" 197 | 198 | core-util-is@1.0.2: 199 | version "1.0.2" 200 | resolved "https://bnpm.byted.org/core-util-is/download/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 201 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 202 | 203 | dashdash@^1.12.0: 204 | version "1.14.1" 205 | resolved "https://bnpm.byted.org/dashdash/download/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" 206 | integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= 207 | dependencies: 208 | assert-plus "^1.0.0" 209 | 210 | decamelize@^1.2.0: 211 | version "1.2.0" 212 | resolved "https://bnpm.byted.org/decamelize/download/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 213 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 214 | 215 | delayed-stream@~1.0.0: 216 | version "1.0.0" 217 | resolved "https://bnpm.byted.org/delayed-stream/download/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 218 | integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= 219 | 220 | didyoumean@^1.2.1: 221 | version "1.2.1" 222 | resolved "https://bnpm.byted.org/didyoumean/download/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff" 223 | integrity sha1-6S7f2tplN9SE1zwBcv0eugxJdv8= 224 | 225 | ecc-jsbn@~0.1.1: 226 | version "0.1.2" 227 | resolved "https://bnpm.byted.org/ecc-jsbn/download/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" 228 | integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= 229 | dependencies: 230 | jsbn "~0.1.0" 231 | safer-buffer "^2.1.0" 232 | 233 | emoji-regex@^8.0.0: 234 | version "8.0.0" 235 | resolved "https://bnpm.byted.org/emoji-regex/download/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 236 | integrity sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc= 237 | 238 | escape-string-regexp@^1.0.5: 239 | version "1.0.5" 240 | resolved "https://bnpm.byted.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 241 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 242 | 243 | extend@~3.0.2: 244 | version "3.0.2" 245 | resolved "https://bnpm.byted.org/extend/download/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" 246 | integrity sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo= 247 | 248 | external-editor@^3.0.3: 249 | version "3.1.0" 250 | resolved "https://bnpm.byted.org/external-editor/download/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" 251 | integrity sha1-ywP3QL764D6k0oPK7SdBqD8zVJU= 252 | dependencies: 253 | chardet "^0.7.0" 254 | iconv-lite "^0.4.24" 255 | tmp "^0.0.33" 256 | 257 | extsprintf@1.3.0: 258 | version "1.3.0" 259 | resolved "https://bnpm.byted.org/extsprintf/download/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" 260 | integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= 261 | 262 | extsprintf@^1.2.0: 263 | version "1.4.0" 264 | resolved "https://bnpm.byted.org/extsprintf/download/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" 265 | integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= 266 | 267 | fast-deep-equal@^3.1.1: 268 | version "3.1.1" 269 | resolved "https://bnpm.byted.org/fast-deep-equal/download/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" 270 | integrity sha1-VFFFB3xQFJHjOxXsQIwpQ3bpSuQ= 271 | 272 | fast-json-stable-stringify@^2.0.0: 273 | version "2.1.0" 274 | resolved "https://bnpm.byted.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 275 | integrity sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM= 276 | 277 | figures@^3.0.0: 278 | version "3.2.0" 279 | resolved "https://bnpm.byted.org/figures/download/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" 280 | integrity sha1-YlwYvSk8YE3EqN2y/r8MiDQXRq8= 281 | dependencies: 282 | escape-string-regexp "^1.0.5" 283 | 284 | find-up@^4.1.0: 285 | version "4.1.0" 286 | resolved "https://bnpm.byted.org/find-up/download/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" 287 | integrity sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk= 288 | dependencies: 289 | locate-path "^5.0.0" 290 | path-exists "^4.0.0" 291 | 292 | forever-agent@~0.6.1: 293 | version "0.6.1" 294 | resolved "https://bnpm.byted.org/forever-agent/download/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" 295 | integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= 296 | 297 | form-data@~2.3.2: 298 | version "2.3.3" 299 | resolved "https://bnpm.byted.org/form-data/download/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" 300 | integrity sha1-3M5SwF9kTymManq5Nr1yTO/786Y= 301 | dependencies: 302 | asynckit "^0.4.0" 303 | combined-stream "^1.0.6" 304 | mime-types "^2.1.12" 305 | 306 | get-caller-file@^2.0.1: 307 | version "2.0.5" 308 | resolved "https://bnpm.byted.org/get-caller-file/download/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 309 | integrity sha1-T5RBKoLbMvNuOwuXQfipf+sDH34= 310 | 311 | getpass@^0.1.1: 312 | version "0.1.7" 313 | resolved "https://bnpm.byted.org/getpass/download/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" 314 | integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= 315 | dependencies: 316 | assert-plus "^1.0.0" 317 | 318 | har-schema@^2.0.0: 319 | version "2.0.0" 320 | resolved "https://bnpm.byted.org/har-schema/download/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" 321 | integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= 322 | 323 | har-validator@~5.1.3: 324 | version "5.1.3" 325 | resolved "https://bnpm.byted.org/har-validator/download/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" 326 | integrity sha1-HvievT5JllV2de7ZiTEQ3DUPoIA= 327 | dependencies: 328 | ajv "^6.5.5" 329 | har-schema "^2.0.0" 330 | 331 | has-flag@^3.0.0: 332 | version "3.0.0" 333 | resolved "https://bnpm.byted.org/has-flag/download/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 334 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 335 | 336 | has-flag@^4.0.0: 337 | version "4.0.0" 338 | resolved "https://bnpm.byted.org/has-flag/download/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 339 | integrity sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s= 340 | 341 | http-signature@~1.2.0: 342 | version "1.2.0" 343 | resolved "https://bnpm.byted.org/http-signature/download/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" 344 | integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= 345 | dependencies: 346 | assert-plus "^1.0.0" 347 | jsprim "^1.2.2" 348 | sshpk "^1.7.0" 349 | 350 | iconv-lite@^0.4.24: 351 | version "0.4.24" 352 | resolved "https://bnpm.byted.org/iconv-lite/download/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 353 | integrity sha1-ICK0sl+93CHS9SSXSkdKr+czkIs= 354 | dependencies: 355 | safer-buffer ">= 2.1.2 < 3" 356 | 357 | inquirer@^7.0.4: 358 | version "7.0.4" 359 | resolved "https://bnpm.byted.org/inquirer/download/inquirer-7.0.4.tgz#99af5bde47153abca23f5c7fc30db247f39da703" 360 | integrity sha1-ma9b3kcVOryiP1x/ww2yR/OdpwM= 361 | dependencies: 362 | ansi-escapes "^4.2.1" 363 | chalk "^2.4.2" 364 | cli-cursor "^3.1.0" 365 | cli-width "^2.0.0" 366 | external-editor "^3.0.3" 367 | figures "^3.0.0" 368 | lodash "^4.17.15" 369 | mute-stream "0.0.8" 370 | run-async "^2.2.0" 371 | rxjs "^6.5.3" 372 | string-width "^4.1.0" 373 | strip-ansi "^5.1.0" 374 | through "^2.3.6" 375 | 376 | is-fullwidth-code-point@^3.0.0: 377 | version "3.0.0" 378 | resolved "https://bnpm.byted.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 379 | integrity sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0= 380 | 381 | is-promise@^2.1.0: 382 | version "2.1.0" 383 | resolved "https://bnpm.byted.org/is-promise/download/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" 384 | integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= 385 | 386 | is-typedarray@~1.0.0: 387 | version "1.0.0" 388 | resolved "https://bnpm.byted.org/is-typedarray/download/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 389 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= 390 | 391 | isstream@~0.1.2: 392 | version "0.1.2" 393 | resolved "https://bnpm.byted.org/isstream/download/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" 394 | integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= 395 | 396 | jsbn@~0.1.0: 397 | version "0.1.1" 398 | resolved "https://bnpm.byted.org/jsbn/download/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" 399 | integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= 400 | 401 | json-fixer@^1.4.0: 402 | version "1.3.3" 403 | resolved "https://bnpm.byted.org/json-fixer/download/json-fixer-1.3.3.tgz#8a11c0536330e44f2aaba8b836d16657ad590dba" 404 | integrity sha1-ihHAU2Mw5E8qq6i4NtFmV61ZDbo= 405 | dependencies: 406 | "@babel/runtime" "^7.5.5" 407 | chalk "^2.4.2" 408 | pegjs "^0.10.0" 409 | 410 | json-schema-traverse@^0.4.1: 411 | version "0.4.1" 412 | resolved "https://bnpm.byted.org/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 413 | integrity sha1-afaofZUTq4u4/mO9sJecRI5oRmA= 414 | 415 | json-schema@0.2.3: 416 | version "0.2.3" 417 | resolved "https://bnpm.byted.org/json-schema/download/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" 418 | integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= 419 | 420 | json-stringify-safe@~5.0.1: 421 | version "5.0.1" 422 | resolved "https://bnpm.byted.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 423 | integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= 424 | 425 | jsprim@^1.2.2: 426 | version "1.4.1" 427 | resolved "https://bnpm.byted.org/jsprim/download/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" 428 | integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= 429 | dependencies: 430 | assert-plus "1.0.0" 431 | extsprintf "1.3.0" 432 | json-schema "0.2.3" 433 | verror "1.10.0" 434 | 435 | locate-path@^5.0.0: 436 | version "5.0.0" 437 | resolved "https://bnpm.byted.org/locate-path/download/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" 438 | integrity sha1-Gvujlq/WdqbUJQTQpno6frn2KqA= 439 | dependencies: 440 | p-locate "^4.1.0" 441 | 442 | lodash@^4.11.2, lodash@^4.17.15: 443 | version "4.17.15" 444 | resolved "https://bnpm.byted.org/lodash/download/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" 445 | integrity sha1-tEf2ZwoEVbv+7dETku/zMOoJdUg= 446 | 447 | mime-db@1.43.0: 448 | version "1.43.0" 449 | resolved "https://bnpm.byted.org/mime-db/download/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" 450 | integrity sha1-ChLgUCZQ5HPXNVNQUOfI9OtPrlg= 451 | 452 | mime-types@^2.1.12, mime-types@~2.1.19: 453 | version "2.1.26" 454 | resolved "https://bnpm.byted.org/mime-types/download/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" 455 | integrity sha1-nJIfwJt+FJpl39wNpNIJlyALCgY= 456 | dependencies: 457 | mime-db "1.43.0" 458 | 459 | mimic-fn@^2.1.0: 460 | version "2.1.0" 461 | resolved "https://bnpm.byted.org/mimic-fn/download/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" 462 | integrity sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs= 463 | 464 | mute-stream@0.0.8: 465 | version "0.0.8" 466 | resolved "https://bnpm.byted.org/mute-stream/download/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" 467 | integrity sha1-FjDEKyJR/4HiooPelqVJfqkuXg0= 468 | 469 | oauth-sign@~0.9.0: 470 | version "0.9.0" 471 | resolved "https://bnpm.byted.org/oauth-sign/download/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" 472 | integrity sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU= 473 | 474 | onetime@^5.1.0: 475 | version "5.1.0" 476 | resolved "https://bnpm.byted.org/onetime/download/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" 477 | integrity sha1-//DzyRYX/mK7UBiWNumayKbfe+U= 478 | dependencies: 479 | mimic-fn "^2.1.0" 480 | 481 | os-tmpdir@~1.0.2: 482 | version "1.0.2" 483 | resolved "https://bnpm.byted.org/os-tmpdir/download/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 484 | integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= 485 | 486 | p-limit@^2.2.0: 487 | version "2.2.2" 488 | resolved "https://bnpm.byted.org/p-limit/download/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" 489 | integrity sha1-YSebZ3IfUoeqHBOpp/u8SMkpGx4= 490 | dependencies: 491 | p-try "^2.0.0" 492 | 493 | p-locate@^4.1.0: 494 | version "4.1.0" 495 | resolved "https://bnpm.byted.org/p-locate/download/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" 496 | integrity sha1-o0KLtwiLOmApL2aRkni3wpetTwc= 497 | dependencies: 498 | p-limit "^2.2.0" 499 | 500 | p-try@^2.0.0: 501 | version "2.2.0" 502 | resolved "https://bnpm.byted.org/p-try/download/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" 503 | integrity sha1-yyhoVA4xPWHeWPr741zpAE1VQOY= 504 | 505 | path-exists@^4.0.0: 506 | version "4.0.0" 507 | resolved "https://bnpm.byted.org/path-exists/download/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 508 | integrity sha1-UTvb4tO5XXdi6METfvoZXGxhtbM= 509 | 510 | pegjs@^0.10.0: 511 | version "0.10.0" 512 | resolved "https://bnpm.byted.org/pegjs/download/pegjs-0.10.0.tgz#cf8bafae6eddff4b5a7efb185269eaaf4610ddbd" 513 | integrity sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0= 514 | 515 | performance-now@^2.1.0: 516 | version "2.1.0" 517 | resolved "https://bnpm.byted.org/performance-now/download/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" 518 | integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= 519 | 520 | pify@^5.0.0: 521 | version "5.0.0" 522 | resolved "https://bnpm.byted.org/pify/download/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" 523 | integrity sha1-H17KP16H6+wozG1UoOSq8ArMEn8= 524 | 525 | psl@^1.1.28: 526 | version "1.7.0" 527 | resolved "https://bnpm.byted.org/psl/download/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" 528 | integrity sha1-8cTEeo75cWfepda79IFtc26ISjw= 529 | 530 | punycode@^2.1.0, punycode@^2.1.1: 531 | version "2.1.1" 532 | resolved "https://bnpm.byted.org/punycode/download/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 533 | integrity sha1-tYsBCsQMIsVldhbI0sLALHv0eew= 534 | 535 | qs@~6.5.2: 536 | version "6.5.2" 537 | resolved "https://bnpm.byted.org/qs/download/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" 538 | integrity sha1-yzroBuh0BERYTvFUzo7pjUA/PjY= 539 | 540 | regenerator-runtime@^0.13.2: 541 | version "0.13.3" 542 | resolved "https://bnpm.byted.org/regenerator-runtime/download/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" 543 | integrity sha1-fPanfY9cb2Drc8X8GVWyzrAea/U= 544 | 545 | request@^2.72.0: 546 | version "2.88.2" 547 | resolved "https://bnpm.byted.org/request/download/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" 548 | integrity sha1-1zyRhzHLWofaBH4gcjQUb2ZNErM= 549 | dependencies: 550 | aws-sign2 "~0.7.0" 551 | aws4 "^1.8.0" 552 | caseless "~0.12.0" 553 | combined-stream "~1.0.6" 554 | extend "~3.0.2" 555 | forever-agent "~0.6.1" 556 | form-data "~2.3.2" 557 | har-validator "~5.1.3" 558 | http-signature "~1.2.0" 559 | is-typedarray "~1.0.0" 560 | isstream "~0.1.2" 561 | json-stringify-safe "~5.0.1" 562 | mime-types "~2.1.19" 563 | oauth-sign "~0.9.0" 564 | performance-now "^2.1.0" 565 | qs "~6.5.2" 566 | safe-buffer "^5.1.2" 567 | tough-cookie "~2.5.0" 568 | tunnel-agent "^0.6.0" 569 | uuid "^3.3.2" 570 | 571 | require-directory@^2.1.1: 572 | version "2.1.1" 573 | resolved "https://bnpm.byted.org/require-directory/download/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 574 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 575 | 576 | require-main-filename@^2.0.0: 577 | version "2.0.0" 578 | resolved "https://bnpm.byted.org/require-main-filename/download/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" 579 | integrity sha1-0LMp7MfMD2Fkn2IhW+aa9UqomJs= 580 | 581 | restore-cursor@^3.1.0: 582 | version "3.1.0" 583 | resolved "https://bnpm.byted.org/restore-cursor/download/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" 584 | integrity sha1-OfZ8VLOnpYzqUjbZXPADQjljH34= 585 | dependencies: 586 | onetime "^5.1.0" 587 | signal-exit "^3.0.2" 588 | 589 | run-async@^2.2.0: 590 | version "2.3.0" 591 | resolved "https://bnpm.byted.org/run-async/download/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" 592 | integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= 593 | dependencies: 594 | is-promise "^2.1.0" 595 | 596 | rxjs@^6.5.3: 597 | version "6.5.4" 598 | resolved "https://bnpm.byted.org/rxjs/download/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" 599 | integrity sha1-4Hd/4NGEzseHLfFH8wNXLUFOIRw= 600 | dependencies: 601 | tslib "^1.9.0" 602 | 603 | safe-buffer@^5.0.1, safe-buffer@^5.1.2: 604 | version "5.2.0" 605 | resolved "https://bnpm.byted.org/safe-buffer/download/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" 606 | integrity sha1-t02uxJsRSPiMZLaNSbHoFcHy9Rk= 607 | 608 | "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: 609 | version "2.1.2" 610 | resolved "https://bnpm.byted.org/safer-buffer/download/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 611 | integrity sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo= 612 | 613 | set-blocking@^2.0.0: 614 | version "2.0.0" 615 | resolved "https://bnpm.byted.org/set-blocking/download/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 616 | integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= 617 | 618 | signal-exit@^3.0.2: 619 | version "3.0.2" 620 | resolved "https://bnpm.byted.org/signal-exit/download/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" 621 | integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= 622 | 623 | sshpk@^1.7.0: 624 | version "1.16.1" 625 | resolved "https://bnpm.byted.org/sshpk/download/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" 626 | integrity sha1-+2YcC+8ps520B2nuOfpwCT1vaHc= 627 | dependencies: 628 | asn1 "~0.2.3" 629 | assert-plus "^1.0.0" 630 | bcrypt-pbkdf "^1.0.0" 631 | dashdash "^1.12.0" 632 | ecc-jsbn "~0.1.1" 633 | getpass "^0.1.1" 634 | jsbn "~0.1.0" 635 | safer-buffer "^2.0.2" 636 | tweetnacl "~0.14.0" 637 | 638 | string-width@^4.1.0, string-width@^4.2.0: 639 | version "4.2.0" 640 | resolved "https://bnpm.byted.org/string-width/download/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" 641 | integrity sha1-lSGCxGzHssMT0VluYjmSvRY7crU= 642 | dependencies: 643 | emoji-regex "^8.0.0" 644 | is-fullwidth-code-point "^3.0.0" 645 | strip-ansi "^6.0.0" 646 | 647 | strip-ansi@^5.1.0: 648 | version "5.2.0" 649 | resolved "https://bnpm.byted.org/strip-ansi/download/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" 650 | integrity sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4= 651 | dependencies: 652 | ansi-regex "^4.1.0" 653 | 654 | strip-ansi@^6.0.0: 655 | version "6.0.0" 656 | resolved "https://bnpm.byted.org/strip-ansi/download/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" 657 | integrity sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI= 658 | dependencies: 659 | ansi-regex "^5.0.0" 660 | 661 | supports-color@^5.3.0: 662 | version "5.5.0" 663 | resolved "https://bnpm.byted.org/supports-color/download/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 664 | integrity sha1-4uaaRKyHcveKHsCzW2id9lMO/I8= 665 | dependencies: 666 | has-flag "^3.0.0" 667 | 668 | supports-color@^7.1.0: 669 | version "7.1.0" 670 | resolved "https://bnpm.byted.org/supports-color/download/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" 671 | integrity sha1-aOMlkd9z4lrRxLSRCKLsUHliv9E= 672 | dependencies: 673 | has-flag "^4.0.0" 674 | 675 | through@^2.3.6: 676 | version "2.3.8" 677 | resolved "https://bnpm.byted.org/through/download/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 678 | integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= 679 | 680 | tmp@^0.0.33: 681 | version "0.0.33" 682 | resolved "https://bnpm.byted.org/tmp/download/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" 683 | integrity sha1-bTQzWIl2jSGyvNoKonfO07G/rfk= 684 | dependencies: 685 | os-tmpdir "~1.0.2" 686 | 687 | tough-cookie@~2.5.0: 688 | version "2.5.0" 689 | resolved "https://bnpm.byted.org/tough-cookie/download/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" 690 | integrity sha1-zZ+yoKodWhK0c72fuW+j3P9lreI= 691 | dependencies: 692 | psl "^1.1.28" 693 | punycode "^2.1.1" 694 | 695 | tslib@^1.9.0: 696 | version "1.11.0" 697 | resolved "https://bnpm.byted.org/tslib/download/tslib-1.11.0.tgz#f1f3528301621a53220d58373ae510ff747a66bc" 698 | integrity sha1-8fNSgwFiGlMiDVg3OuUQ/3R6Zrw= 699 | 700 | tunnel-agent@^0.6.0: 701 | version "0.6.0" 702 | resolved "https://bnpm.byted.org/tunnel-agent/download/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" 703 | integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= 704 | dependencies: 705 | safe-buffer "^5.0.1" 706 | 707 | tweetnacl@^0.14.3, tweetnacl@~0.14.0: 708 | version "0.14.5" 709 | resolved "https://bnpm.byted.org/tweetnacl/download/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" 710 | integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= 711 | 712 | type-fest@^0.8.1: 713 | version "0.8.1" 714 | resolved "https://bnpm.byted.org/type-fest/download/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" 715 | integrity sha1-CeJJ696FHTseSNJ8EFREZn8XuD0= 716 | 717 | uri-js@^4.2.2: 718 | version "4.2.2" 719 | resolved "https://bnpm.byted.org/uri-js/download/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" 720 | integrity sha1-lMVA4f93KVbiKZUHwBCupsiDjrA= 721 | dependencies: 722 | punycode "^2.1.0" 723 | 724 | uuid@^3.3.2: 725 | version "3.4.0" 726 | resolved "https://bnpm.byted.org/uuid/download/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" 727 | integrity sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4= 728 | 729 | verror@1.10.0: 730 | version "1.10.0" 731 | resolved "https://bnpm.byted.org/verror/download/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" 732 | integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= 733 | dependencies: 734 | assert-plus "^1.0.0" 735 | core-util-is "1.0.2" 736 | extsprintf "^1.2.0" 737 | 738 | which-module@^2.0.0: 739 | version "2.0.0" 740 | resolved "https://bnpm.byted.org/which-module/download/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" 741 | integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= 742 | 743 | wrap-ansi@^6.2.0: 744 | version "6.2.0" 745 | resolved "https://bnpm.byted.org/wrap-ansi/download/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" 746 | integrity sha1-6Tk7oHEC5skaOyIUePAlfNKFblM= 747 | dependencies: 748 | ansi-styles "^4.0.0" 749 | string-width "^4.1.0" 750 | strip-ansi "^6.0.0" 751 | 752 | y18n@^4.0.0: 753 | version "4.0.0" 754 | resolved "https://bnpm.byted.org/y18n/download/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" 755 | integrity sha1-le+U+F7MgdAHwmThkKEg8KPIVms= 756 | 757 | yargs-parser@^16.1.0: 758 | version "16.1.0" 759 | resolved "https://bnpm.byted.org/yargs-parser/download/yargs-parser-16.1.0.tgz#73747d53ae187e7b8dbe333f95714c76ea00ecf1" 760 | integrity sha1-c3R9U64YfnuNvjM/lXFMduoA7PE= 761 | dependencies: 762 | camelcase "^5.0.0" 763 | decamelize "^1.2.0" 764 | 765 | yargs@^15.0.1: 766 | version "15.1.0" 767 | resolved "https://bnpm.byted.org/yargs/download/yargs-15.1.0.tgz#e111381f5830e863a89550bd4b136bb6a5f37219" 768 | integrity sha1-4RE4H1gw6GOolVC9SxNrtqXzchk= 769 | dependencies: 770 | cliui "^6.0.0" 771 | decamelize "^1.2.0" 772 | find-up "^4.1.0" 773 | get-caller-file "^2.0.1" 774 | require-directory "^2.1.1" 775 | require-main-filename "^2.0.0" 776 | set-blocking "^2.0.0" 777 | string-width "^4.2.0" 778 | which-module "^2.0.0" 779 | y18n "^4.0.0" 780 | yargs-parser "^16.1.0" 781 | --------------------------------------------------------------------------------