iOS面试题-Swift篇(一)

240 阅读7分钟

这篇文章主要介绍了iOS面试题-Swift篇,对大家的学习或者工作具有一定的参考学习价值,感兴趣的小伙伴们可以了解一下哦

介绍Swift

Swift是苹果在2014年6月WWDC发布的全新编程语言,借鉴了JS,Python,C#,Ruby等语言特性,看上去偏脚本化,Swift 仍支持 cocoa touch 框架

Swift的优点:

  1. Swift更加安全,它是类型安全的语言。
  2. Swift容易阅读,语法和文件结构简易化。
  3. Swift更易于维护,文件分离后结构更清晰。
  4. Swift代码更少,简洁的语法,可以省去大量冗余代码
  5. Swift速度更快,运算性能更高

Swift 和OC 如何相互调用?

Swift 调用 OC代码

需要创建一个 Target-BriBridging-Header.h 的桥文件,在乔文件导入需要调用的OC代码头文件即可

OC 调用 Swift代码

直接导入 Target-Swift.h文件即可, Swift如果需要被OC调用,需要使用@objc 对方法或者属性进行修饰

类(class) 和 结构体(struct) 有什么区别

在 Swift 中,class 是引用类型(指针类型), struct 是值类型

值类型

值类型在传递和赋值时将进行复制; 赋值给var、let或者给函数传参,是直接将所有内容拷贝一份, 类似于对文件进行copy、paste操作,产生了全新的文件副本。属于深拷贝(deep copy) 值类型: 比如结构体,枚举,是在栈空间上存储和操作的

引用类型

引用类型只会使用引用对象的一个"指向"; 赋值给var、let或者给函数传参,是将内存地址拷贝一份,类似于制作一个文件的替身(快捷方式、链接),指向的是同一个文件。属于浅拷贝(shallow copy) 引用类型: 比如 Class,是在堆空间上存储和操作的

class 和 struct 比较,优缺点

  1. class 有以下功能,struct 是没有的
  2. class可以继承,子类可以使用父类的特性和方法
  3. 类型转换可以在运行时检查和解释一个实例对象
  4. class可以用 deinit来释放资源
  5. 一个类可以被多次引用

struct 优势: 结构较小,适用于复制操作,相比较一个class 实例被多次引用,struct 更安全 无需担心内存泄露问题

Swift 中,什么可选型(Optional)

  1. 在 Swift 中,可选型是为了表达一个变量为空的情况,当一个变量为空,他的值就是 nil
  2. 在类型名称后面加个问号? 来定义一个可选型
  3. 值类型或者引用类型都可以是可选型变量
var name: String? // 默认为 nil
var age: Int?     // 默认为nil
print(name, age) // 打印 nil, nil

Swift,什么是泛型?

泛型主要是为增加代码的灵活性而生的,它可以是对应的代码满足任意类型的的变量或方法; 泛型可以将类型参数化,提高代码复用率,减少代码量

// 实现一个方法,可以交换实现任意类型
func swap<T>(a: inout T, b: inout T) {
    (a, b) = (b, a)
}

访问控制关键字 open, public, internal, fileprivate, private 的区别?

Swift 中有个5个级别的访问控制权限,从高到低依次是 open, public, internal, fileprivate, private

它们遵循的基本规则: 高级别的变量不允许被定义为低级别变量的成员变量,比如一个 private 的 class 内部允许包含 public的 String值,反之低级变量可以定义在高级别变量中;

open: 具备最高访问权限,其修饰的类可以和方法,可以在任意 模块中被访问和重写. public: 权限仅次于 open,和 open 唯一的区别是: 不允许其他模块进行继承、重写 **internal:**默认权限, 只允许在当前的模块中访问,可以继承和重写,不允许在其他模块中访问 fileprivate: 修饰的对象只允许在当前的文件中访问; private: 最低级别访问权限,只允许在定义的作用域内访问

关键字:Strong,Weak,Unowned 区别

  1. Swift 的内存管理机制同OC一致,都是ARC管理机制; Strong,和 Weak用法同OC一样
  2. Unowned(无主引用), 不会产生强引用,实例销毁后仍然存储着实例的内存地址(类似于OC中的unsafe_unretained), 试图在实例销毁后访问无主引用,会产生运行时错误(野指针

如何理解copy-on-write?

值类型(比如:struct),在复制时,复制对象与原对象实际上在内存中指向同一个对象,当且仅当修改复制的对象时,才会在内存中创建一个新的对象

  1. 为了提升性能,Struct, String、Array、Dictionary、Set采取了Copy On Write的技术
  2. 比如仅当有“写”操作时,才会真正执行拷贝操作
  3. 对于标准库值类型的赋值操作,Swift 能确保最佳性能,所有没必要为了保证最佳性能来避免赋值

什么是属性观察

属性观察是指在当前类型内对特性属性进行监测,并作出响应,属性观察是 swift 中的特性,具有2种, willset 和 didset

var title: String {
    willSet {
        print("willSet", newValue)

    }
    didSet {
        print("didSet", oldValue, title)
    }
}

willSet会传递新值,默认叫newValue didSet会传递旧值,默认叫oldValue 在初始化器中设置属性值不会触发willSet和didSet

swift 为什么将 String,Array,Dictionary设计为值类型

值类型和引用类型相比,最大优势可以高效的使用内存,值类型在栈上操作,引用类型在堆上操作,栈上操作仅仅是单个指针的移动,而堆上操作牵涉到合并,位移,重链接,Swift 这样设计减少了堆上内存分配和回收次数,使用 copy-on-write将值传递与复制开销降到最低

如何将Swift 中的协议(protocol)中的部分方法设计为可选(optional)?

  1. 在协议和方法前面添加 @objc,然后在方法前面添加 optional关键字,改方式实际上是将协议转为了OC的方式
@objc protocol someProtocol {
  @objc  optional func test()
}
  1. 使用扩展(extension),来规定可选方法,在 swift 中,协议扩展可以定义部分方法的默认实现
protocol someProtocol {
    func test()
}

extension someProtocol{
    func test() {
        print("test")
    }
}

比较Swift 和OC中的初始化方法 (init) 有什么不同

swift 的初始化方法,更加严格和准确, swift初始化方法需要保证所有的非optional的成员变量都完成初始化, 同时 swfit 新增了convenience和 required两个修饰初始化器的关键字

  • convenience只提供一种方便的初始化器,必须通过一个指定初始化器来完成初始化
  • required是强制子类重写父类中所修饰的初始化方法

比较 Swift和OC中的 protocol 有什么不同

相同点: 两者都可以被用作代理; 不同点: Swift中的 protocol还可以对接口进行抽象,可以实现面向协议,从而大大提高编程效率,Swift中的protocol可以用于值类型,结构体,枚举;

swift 和OC 中的自省 有什么区别

自省在OC中就是判断某一对象是否属于某一个类的操作,有以下2种方式

[obj iskinOfClass:[SomeClass class]]
[obj isMemberOfClass:[SomeClass class]]

在 Swift 中由于很多 class 并非继承自 NSObject, 故而 Swift 使用 is 来判断是否属于某一类型, is 不仅可以作用于class, 还是作用于enum和struct

什么是函数重载? swift 支不支持函数重载?

函数重载是指: 函数名称相同,函数的参数个数不同, 或者参数类型不同,或参数标签不同, 返回值类型与函数重载无关 swift 支持函数重载

swift 中的枚举,关联值 和 原始值的区分?

关联值--有时会将枚举的成员值跟其他类型的变量关联存储在一起,会非常有用

// 关联值
enum Date {
case digit(year: Int, month: Int, day: Int)
case string(String)
}

原始值--枚举成员可以使用相同类型的默认值预先关联,这个默认值叫做:原始值

// 原始值
enum Grade: String {
  case perfect = "A"
  case great = "B"
  case good = "C"
  case bad = "D"
}

以上就是全文内容,希望对大家有所帮助

收录:原文地址