iOS面试题:Swift

张建 lol

swift 和 oc 的区别?重点

  • swift静态语言,有 类型判断OC动态语言
  • Swift类型安全 的语言。OC 类型不安全的语言。
  • swift 可以面向 函数、协议、对象 编程。OC面向对象 编程为主。
  • Swift 注重 值类型OC 注重 引用类型
  • Swift 支持 静态派发、动态派发(函数表派发、消息派发)。OC 支持 动态派发(消息派发)
  • swift 代码更简洁、运行速度更快、性能更好。

静态语言:静态类型语言,数据类型 是在 编译 期间检查的语言
动态语言:动态类型语言,数据类型 是在 运行 期间检查的语言

OC和Swift 方法的调用 区别?重点面试题

  1. OC 支持 动态派发(消息派发),运行时才确定方法的实现。

  2. swift 支持 静态派发和动态派发 来确定方法的实现。

  • 静态派发

    • 静态派发是指在 运行时 调用方法 不需要查表,直接跳转到方法的代码中执行。

    • 静态派发是有条件的,方法内部的代码必须对编译器透明,并且在运行时不能被更改,这样编译器才能帮助我们。

    • Swift中的 值类型 不能被继承,也就是说值类型的方法实现不能被修改或者被复写,因此值类型的方法 满足静态派发 的要求。

    • class 中将方法标记为。final 或者 private 就是静态调度。

    • 内联是指在编译期把每一处方法调用替换为直接执行方法内部的代码,可以帮助你避免运行时方法调用的时间开销。

  • 动态派发

    • 动态派发 需要查表 。即 函数表调用

    • Swift中的 会创建一个 V-Table,这个Table是一个数组,其中存放的是 函数指针

    • 子类会按照父类 V-Table 中函数的存放,如果子类没有覆盖某个方法,那么就会拷贝父类方法的地址,如上面的例子会得到下面的V-Table。

    • 将函数指针和Index所做的映射在编译期就确定了,这就大大减少了运行时的工作量,提高了运行速度。所以在运行时它没有必要知道是哪个类型的实例调用了这个方法,只需要找到相应的V-Table即可,至于是其中的哪个Index,已经在编译期确定了,没必要再去查找Index的值。

权限修饰符 面试重点

  • open:修饰的属性或者方法在 其他作用域既可以被访问也可以被继承或重载 override

  • public :修饰的属性或者方法可以在 其他作用域允许被访问但不能被重载,也不能在继承的 Extension 中被访问

  • internal:被修饰的属性和方法只能在 模块内 部可以访问,超出模块内部就不可被访问了。(默认)

  • fileprivate :其修饰的属性或者方法只能在当前的 源文件 里可以访问。

  • private :只允许在 当前类 中调用,Extension 中不能访问

  • 从高到低排序如下:

open > public > interal > fileprivate > private

swift 是面向对象还是函数式编程? 重点

  • swift 既是面向对象也是面向函数式编程

  • swift面向对象,是因为swift支持 类的封装、继承、多态

  • swift面向函数式编程,是因为swift支持 map、reduce、filter、compactMap、flatMap 这类 去除中间状态、数学函数式方法,更加强调 运算结果 而不是中间过程。

swift中高阶函数有几种?分别讲解一下? 重点

  • map 对给定数组每一个元素,执行闭包中的 映射 操作,将映射结果放置在数组中返回
1
2
3
4
5
// 数字数组子元素转换为字符串
let arr: NSArray = [1,3,4];
print(arr.map { "\($0)" });
=======
["1", "3", "4"]
  • filter 对给定数组的每一个元素,执行闭包中的 过滤 操做,将符合条件的元素放在数组中返回
1
2
3
4
5
// 筛选偶数
let arr: NSArray = [1,3,4];
print(arr.filter { $0 as! Int%2 == 0 });
========
[4]
  • reduce 对给定数组的每一个元素,执行闭包中的 合并 操作,并将合并结果返回
1
2
3
4
5
6
7
// 转换为字符串并拼接
let arr: NSArray = [1,3,4];
print(arr.reduce("") { $0 + "\($1)"});
print(type(of: arr.reduce("") { $0 + "\($1)"}));
=========
134
String
  • compactMap 对给定数组的每一个元素,执行闭包中的 映射 操作,将非空的映射结果放置在数组中返回
1
2
3
4
let arr2 = [1,2,3,nil];
print(arr2.compactMap { $0 });
=======
[1,2,3]
  • flatMap 对给定数组的每一个元素,执行闭包中的 降维 操作,将映射的结果防止在数组中返回
1
2
3
4
let arr3 = [[1,2],[3,4]];
print(arr3.flatMap { $0 });
=====
[1, 2, 3, 4]

什么是类?什么是结构体?重点

structclass 都是 构建代码的一种通用且灵活的构造体。

struct 和 class 区别? 重点

  • struct、class 共同点:

    • 定义 属性 用于 存储值
    • 定义 方法 用于 提供功能
    • 定义 下标脚本 用于 访问值
    • 定义 初始化器 用于 生成初始化值
    • 定义 扩展增加默认实现的功能
    • 定义 协议提供标准功能
  • struct、class 不同点:

    • class 定义 属性,必须赋值或包装成 Optional。struct 定义属性不需要要赋值
    • class 是 引用类型,分配在 中,动态分配释放内存,浅拷贝。struct 是 值类型,分配在 中,系统分配释放内存,深拷贝
    • class 可以继承 ,。struct 不能继承
    • class 有 引用计数,可以 多次引用。struct 没有引用计数
    • class 有 类型转换,允许在 运行时检查和解释一个类实例的类型。struct 没有
    • class 有 反初始化器 deinit 用于 释放资源
    • struct 比 class 更轻量级 只访问一次拿到数据, 访问两次拿到数据(第一次
      获取指针,第二次获取数据)

类的指定初始化器和便捷初始化器?

类的初始化器代理规则

  • 指定初始化器必须调用其直接父类的指定初始化器
  • 便捷初始化器必须调从同类调用一个指定初始化器
  • 便捷初始化器最终必须调用一个指定初始化器

更方便的记忆方法

  • 指定初始化器必须总是向上代理
  • 便捷初始化器必须是横向代理

什么是闭包?重点

代码中可以 被传递和引用的功能性独立的代码块

闭包作用?重点

  • 闭包 可以 捕获和存储上下文的常量和变量闭包 实现上是一个 结构体

  • 闭包 可以作为函数 参数,也可以作为函数的 返回值

  • 闭包可以像 oc 中用于 回调和反向传值

闭包的几种类型?重点

  • 尾随闭包:闭包作为函数最后一个参数

  • 逃逸闭包:用 @escaping 修饰,函数返回之后调用

  • 自动闭包:用 @autoclosure 修饰,延迟执行,即 调用的时候才执行

Optional是什么?

  • Object-C 中用 nil 表示 指向不存在对象的指针,其他地方用 NSNotFound 表示 值缺失

  • Swift 中用 可选(Optional)类型 表示 值缺失,只有可选类型才能设置为 nil

  • Optional 含有两种枚举,NoneSome(T),用来 表示可能有值或可能没有值

  • Swift 中只有 Optional 才能设置为 nil,用 ?Optional<数据类型>

如何使用 Optional?

  • 强制解包: !

  • 数据类型: != nil

  • 可选绑定:if 赋值给常量或变量

  • 隐士解包:直接 ! 初始化值

swift类型?Swiift 值类型 和 引用类型的区别?特点?

  • swift的类型分为 值类型引用类型

    • 值类型:如 struct、enum、Int、Float、Bool、String、Array、Dictionary、String 等都是 值类型

    • 引用类型: 如 class类型、closure闭包、函数 等为 引用类型

  • 区别

    • 值类型:传递和存储 是一个 副本,使用过程中 不会影响源数据,存储在 栈区,访问一次拿到数据

    • 引用类型:传递和存储本身(内存地址),使用过程中会 影响源数据,存储在 堆区,访问两次拿到数据,栈区拿到 指针地址,指针地址到堆区拿到 内存地址

什么是函数?

  • 函数是 一个独立的代码块,由 名字、参数、返回值 组成。

  • 函数类型由 形式参数类型和返回类型 决定

  • 全局函数和内嵌函数时 特殊的闭包

  • 函数是 引用类型,存储在

什么是枚举?oc 与 swift 枚举有啥区别?

  • 枚举 是一种 数据类型,只包含自定义的特定数据,值类型,存储在 栈区

  • OC ,枚举只支持 整数型,很鸡肋

  • Swift 中枚举有很多功能:

    • 可以定义 成员类型、计算属性、类型属性(不能定义存储属性)、方法
    • 可以定义 下标脚本 用于 获取值
    • 可以定义 初始化器 用于 生成初始化值
    • 可以定义 扩展增加默认实现的功能
    • 可以定义 遵守协议(protocol)提供标准化功能
    • 可以定义 嵌套枚举、递归枚举

泛型的作用?

解决代码的复用性和抽象能力

Swift 中的 KVC 和 KVO

  • KVC:要继承 NSObject
  • KVO:由于 Swift 为了效率, 默认禁用了 动态派发, 因此 Swift 要实现 KVO, 除了要继承自 NSObject 外还要将观测的对象标记为 dynamic (让 swift 代码也能有 Objective-C 中的动态机制)

什么是协议?作用?

  • 协议 规定了用来实现某一特定功能所必须的属性和方法,这个属性指 实例属性或类属性,而不用指定是 存储属性或计算属性
  • 类、结构体、枚举 都可以遵循协议,提供具体的实现 来完成协议定义的 属性和方法

swift 协议 和 oc 协议有啥区别?

swift 协议:

  • 协议可以定义 属性和方法, 定义 属性 必须明确是 可读的/可读可写 { set get }
  • 协议可以定义 继承 其他协议
  • 协议可以定义 扩展协议
  • 协议可以定义 指定初始化器或便捷初始化器
  • 协议可以用于 类、结构体、枚举

oc 协议:

  • 受限于委托代理,多用于不同类之间的传值和回调

什么是扩展?作用?

1、扩展可以向一个已有的 类型、结构体、枚举、协议 添加新的功能

2、作用:

  • 可以添加 计算型实例属性计算型类型属性
  • 可以添加 实例方法和类型方法
  • 可以添加 新的初始化器
  • 可以添加 下标脚本
  • 可以使现有的 类型遵循某协议
  • 定义和使用 新内嵌类型
  • 扩展 可以向一个类型添加新的方法,但是不能重写已有的方法

使用注意:

  • 不可以添加 存储属性属性观察器

associatedtype 关键字作用?

  • 关联类型:给 协议 中用到的 某个类型 起一个 占位符名称

final 关键字作用?

  • final:只能用于 中, final 声明的 不能被继承,final 声明的 属性、方法不能被重写

inout 关键字作用?

  • inout: 输入输出形式参数,用来 修改形式参数的值,函数结束后仍然生效,因为函数的参数是 值类型

@objc 关键字作用?

  • @objc:用于 OC 访问 swift 需要继承 NSObject

dynamic 关键字作用?

  • dynamic :让方法具有动态性,用于 method-swizzling, 需要 继承 NSObject

  • @objc + dynamic :用来实现消息发送

mutaing 关键字作用?

  • mutaing:结构体内嵌函数修改存储属性

dynamic framework 和 static framework 的区别是什么?

  • 静态库和动态库, 静态库是每一个程序单独打包一份, 而动态库则是多个程序之间共享.

  • 静态库和动态库是相对编译期和运行期的:静态库在程序编译时会被链接到目标代码中,程序运行时将不再更改静态库;而 动态库 在程序编译时并不会被链接到目标代码中,只是在 程序运行时 才被载入。

  • 静态库在链接时,会被完整的 复制 到可执行文件中,如果多个App都使用了同一个静态库,那么每个App都会拷贝一份,缺点是 浪费内存.

  • 动态库不会复制,只有一份,程序运行时动态加载到内存中,系统只会加载一次,多个程序共用一份,节约了内存.

常用的三方框架

  • Alamofire:网络加载
  • HandyJson:JSON数据解析
  • RxSwift:响应式编程
  • Snapkit:自动布局
  • MZRefresh:刷新加载
  • Kingfisher:网络图片加载和缓存
  • Post title:iOS面试题:Swift
  • Post author:张建
  • Create time:2023-03-01 16:57:50
  • Post link:https://redefine.ohevan.com/2023/03/01/面试题/Swift面试题:总结/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.