block和闭包对值的捕获差异
OC的block对外部变量的捕获
OC中,block
捕获的值是block
**初始化时上下文**中变量的瞬时值,也就是一个常量
1 | -(void)testBlock { |
捕获__block
修饰的变量时,将变量捕获到堆区,外部的修改会影响内部捕获的值(其实是捕获了内存地址)
1 | -(void)testBlock { |
OC中,block
捕获的值是block
**初始化时上下文**中变量的瞬时值,也就是一个常量
1 | -(void)testBlock { |
捕获__block
修饰的变量时,将变量捕获到堆区,外部的修改会影响内部捕获的值(其实是捕获了内存地址)
1 | -(void)testBlock { |
Swift的表达式和函数的编译时长检查
在build setting
的Other Swift Flags
中设置:
1 | // 编译耗时超过 100ms 的函数或表达式给出警告 |
查看总耗时
在终端执行如下命令,重启Xcode,编译后可以看到总耗时:
1 | defaults write com.apple.dt.Xcode ShowBuildOperationDuration -bool YES |
pch
文件:删除使用不多的引用.h
文件:减少.h
文件中的引用,将.h
中导入改为声明#import
改为@class
对于编译型语言来说,从源码到可执行文件需要经过编译、汇编和链接三个步骤。编译器接收源代码,输出目标代码(也就是汇编代码),汇编器接收汇编代码,输出由机器码组成的目标文件(二进制格式,.o 后缀),最后链接器将各个目标文件链接起来,执行重定位,最终生成可执行文件。
LLVM采用三相设计:
Objective-C/C/C++ 使用的编译器前端是Clang
,swift 是swiftc
,后端都是 LLVM。
App启动分为冷启动和热启动,启动时间由两个阶段构成:
pre-main
阶段:main()
函数之前所需要的时间main()
及main()
之后需要的时间App启动后,首先,系统内核(Kernel)创建一个进程。
加载可执行文件。(可执行文件是指Mach-O
格式的文件,也就是App中所有.o
文件的集合体)这时,能获取到dyld(dyld是苹果的动态链接器)的路径。
加载dyld,主要分为4步:
(1)load dylibs:这一阶段dyld
会分析应用依赖的dylib
,找到其Mach-O
文件,打开和读取这些文件并验证其有效性,接着会找到代码签名注册到内核,最后对dylib
的每一个segment调用mmap()
(在Linux中,使用mmap()用来在进程虚拟内存地址空间中分配地址空间,创建和物理内存的映射关系)。
(2)rebase/bind:进行rebase
指针调整和bind
符号绑定。
(3)ObjC setup:runtime运行时初始化。包括ObjC相关Class的注册、category注册、selector唯一性检查等。
AutoreleasePool底层涉及的数据结构:__AtAutoreleasePool
和AutoreleasePoolPage
调用了autorelease
的对象最终都是通过AutoreleasePoolPage
对象来管理的。
AutoreleasePoolPage
结构
每个AutoreleasePoolPage
对象占用4096个字节
存放Page自身的成员变量和autorelease对象
Page自身是栈结构
Page与Page之间通过parent
和child
指针连接成双向链表
在使用swift原生api对字符串进行处理时,发现其处理效率特别低。经过测试对比发现,处理大量数据时,相同长度的数组和字符串,数组的处理能力可以达到字符串的几十倍。测试代码如下:
1 | func testStringCount() { |
打印结果如下:
编译后的分类信息都保存在category_t
结构体中(定义在objc-runtime-new.h
中):
Category
中的方法是在程序运行时通过runtime
动态地将分类中的方法合并到类对象、元类对象中。
Category
数据(方法、属性、协议);Category
的方法、属性、协议数据,合并到一个大数组中,参与编译的Category
数据,会放在数组的前面struct category_t
;runtime
会将Category
的数据合并到类信息中(类对象、元类对象中)卡顿检测的方案根据线程是否相关分为两大类:
与主线程相关的检测方案:
与主线程不相关的检测方案:
给你一个 m
行 n
列的矩阵 matrix
,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例1
1 | 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] |
示例2
1 | 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] |
提示
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
1 | func spiralOrder(_ matrix: [[Int]]) -> [Int] { |