• Swift常见面试题汇总
  • 发布于 2个月前
  • 86 热度
    0 评论
前言
Swift 初始化在整个编码过程中起着至关重要的作用,在求职面试中,也经常会被问到相关的问题,我整理了相关的一些面试题,并尝试解答一下我的理解。

1. 什么是初始化方法?
这个题问的非常宽泛,可以简单描述一下,也可以结合下边的其他答案深入回答。初始化方法是一种特殊的方法,用于创建类、结构体的实例。初始化方法的主要作用是确保实例中的所有属性都被赋予合适的初始值,必须为没有初始值的存储属性设置初始值。

通过初始化方法,可以在创建实例时进行必要的设置和初始化操作,从而确保实例的正确性和完整性。

2. 类和结构体的初始化有什么区别?
类有继承特性,所以在初始化时需要考虑父类的初始化,结构体则不需要

对于类来说,如果所有属性都有默认值,那么它会自动生成一个默认的初始化方法。而结构体不管属性有没有默认值都会自动生成一个成员逐一初始化方法。


3. 为什么类的属性没有默认值时不会自动生成初始化方法?
主要原因还是类具有继承特性,它和结构体存在根本差异,结构体只需要负责初始化自己的成员变量就可以了,但是类还需要负责其父类的初始化,而且父类中可能有自己的初始化方法。所以情况比较复杂,如果也像结构体一样默认生成初始化方法,则可能产生歧义和一些潜在的问题。

4. 自定义结构体和类中可以写多个初始化方法吗?
可以,比如:
struct SPoint {
    var x: Int
    var y: Int

    init(x: Int, y: Int) {
        self.x = x
        self.y = y
    }
    
    init(x: Int) {
        self.x = x
        self.y = 0
    }
}

class CPoint {
    var x: Int
    var y: Int

    init(x: Int, y: Int) {
        self.x = x
        self.y = y
    }
    
    init(x: Int) {
        self.x = x
        self.y = 0
    }
}
5. 讲讲 swift 中的 convenience 关键字?
在 Swift 中,convenience 关键字用来定义一个类中的便利初始化方法,需要在初始化方法的前面加上convenience关键字,例如:
convenience init() {
    // Initialization code here
}
convenience 关键字声明的初始化方法是为了可以提供更方便的初始化方式,而不需要重复编写初始化逻辑。

但需要注意的是:
.便利初始化方法必须用在类上,不能用在结构体或者枚举上。
.便利初始化方法的实现中必须调用其他的初始化方法。

6. 什么是初始化委派 Initializer Delegation?
简单来说,在一个初始化方法中调用另一个初始化方法,这个过程称为 Initializer Delegation,可避免在多个初始值设定项之间重复代码。

例如:
struct SPoint {
    var x: Int
    var y: Int
    
    init() {
        self.init(x: 0, y: 0)
    }

    init(x: Int, y: Int) {
        self.x = x
        self.y = y
    }
}
7. 什么是两阶段初始化?
两阶段初始化是类初始化的两个过程,确保其所有属性都已正确初始化,并且其父类的初始化在开始初始化其自己的属性之前已完成。在第一阶段,每个存储属性都由引入它的类分配一个初始值。一旦确定了每个存储属性的初始状态,第二阶段就开始了,每个类都有机会在新实例被认为可以使用之前进一步自定义其存储属性,比如调用方法或者执行其他动作。

8. 什么是可失败的初始化方法,什么场景使用?
Swift 设计了一种可以返回 nil 的初始化方法,可以在 init 后加上一个问号来实现这个能力。使用场景也非常广泛,比如你的初始化方法中可能传入了非预期的值,这时无法正常生成一个实例,就可以使用这种方法来返回一个 nil。

系统库中就有大量应用,比如将一个字符串转为数字,传入的字符串有可能不能转成数字,则会返回nil。
let number = Int("a") // nil
9. required 修饰符有什么用?
可以在类初始化方法定义之前加上 required 修饰符,用来标记这个类的每个子类都必须实现这个初始化方法,以保证某些属性被传入:
class Animal {
    var name: String
    var age: Int = 0
    required init(name: String) {
        self.name = name
    }
}

class Dog: Animal {
    required init(name: String) {
        super.init(name: name)
    }
    
    convenience init(name: String, age: Int) {
        self.init(name: name)
        self.age = age
    }
}
以上就是我对这些面试题的理解,可能有不对的地方,大家也可以和我共同探讨。
用户评论