1、下面两段创建Swift的代码有区别吗?如果有,请说明一下。

1
2
3
4
5
// code1
let a = String("test")

// code2
let b = "\("test")"

答:
code1是使用字符串初始化器来创建字符串
code2是使用字符串插值的方式来创建字符串。

字符串插值优缺点:

  • 优点:

(1)可以构建复杂的字符串,可以直接把多个变量或表达式组成一个完整的字符串

(2)编译器会进行优化进,进行常量字符串合并,减少内存分配的开销

  • 缺点:

构造字符串形式单一,特定的类型无法直接转换成字符串

初始化构造器优缺点:

  • 优点:

其他类型转换成字符串类型就必须使用特定的字符串初始化构造器,即可以实现字符串创建的多样化

  • 缺点:

初始化构造器会涉及内存分配开销,性能上不如字面量插值的方式

2、请简述Swift中throws 和 rethrows的区别?

答:

throws:标记函数可能会抛出异常,调用函数的地方需要处理可能抛出的异常。

rethrows:函数本身不会抛出异常,如果作为参数的闭包抛出了异常,则会继续往上抛出异常,可以理解为传递throw。

3、讲一讲字符串类型 String 和 NSString 之间有什么区别?

答:

(1)String是值类型,NSString是引用类型,性能开销上有差异(常见的比如字符串赋值操作、频繁的创建或销毁字符串)

(2)NSString有特定的api,比如常用获取指定字符串的Range

(3)String是可变的,NSString是不可变字符串

4、与OC相比你认为Swift有什么优势?

答:

  • Swift是强类型语言,注重值类型,有类型推断,安全性高

  • Swift的语法更简洁,使用起来方便,支持函数式编程和

  • Swift拥有更强大的特性,它有元组类型、支持可选类型(optional)、支持运算符重载、支持泛型、支持静态/动态派发,协议不仅可以被类实现还可以被struct和enum实现

  • Swift支持命名空间、函数支持默认参数

  • Swift的错误处理机制更完善

5、平时用过哪些Swift的高阶函数?简述一下map、flatMap、compactMap的区别。

答:

swift中常见的高阶函数有:filter、reduce、map、flatMap、compactMap

map:给定数组中的取出值,对其应用一个函数,再将函数的结果返回到新容器中

compactMap:与map函数的功能一致,它会从结果的集合中过滤掉nil,解包可选值

flatMap:与map函数的功能一致,它会打平结果集合(比如二维数组会变成一个新的一维数组)

6、Swift协议中能使用泛型作为参数吗?

答:

在Swift的协议中不能直接使用泛型作为参数,但是我们可以通过Associated Type来实现泛型作为函数参数的功能。

7、在Swift的访问控制权限中public和open关键字有啥区别?平时有用过吗?

答:

public 和 open 的访问权限都是允许在模块的外部进行访问。

open 是可以允许被重写或子类化,而 public 则是不允许其被重写或子类化。

open 关键字在组件化工程中使用的比较多。

8、在Swift中如何防止父类方法被重写?如何让子类必须重写父类指定的方法?

答:

在Swift中防止父类方法被重写:可以在父类方法前加上final关键字。

让子类必须重写父类指定方法:可以在父类中定义required方法

9、如下代码可能会出现什么问题?请详情说明一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// code
struct Person {
var name: NSString?
var age: Int?
}
var person = Person(name: "yyy", age: 12)

for _ in 0..<5 {
DispatchQueue.global().async {
let currentName = person.name
let newName = "\(currentName ?? "") ** ddd"
person.name = newName as NSString
print("the name is update: \(person.name ?? "")")
}
}

答:

Person 中的name属性 NSString 是引用类型,会存在线程安全问题,建议改成值类型 String
在Swift中除非特别需要,否则字符串建议都使用String类型

10、如下代码可能会出现什么问题?请说明原因。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Teacher {
lazy var age: Int = {
print("the teacher age old")
return 12
}()
}

let teacher = Teacher()

for _ in 0..<5 {
DispatchQueue.global().async {
print("the teacher age is: \(teacher.age)")
}
}

答:

(1)首先在Swift中struct是不能包含lazy存储属性,要想使用lazy属性,可以使用class,如果想在struct中延迟加载某属性,可以使用计算属性。

(2)lazy不是线程安全的,应当注意多线程安全的问题

完整优秀版请移步小专栏:
Swift面试题2024(附答案)

更多好文推荐,关注《iOS开发秘籍》,免费解锁完整版

本文内容中部分来自网络,后续会持续更新完善。欢迎一起学习交流!

如需转载,请注明出处

Swift面试题2024(附答案)