美文网首页
2021 Swift 面试基础复习回顾

2021 Swift 面试基础复习回顾

作者: 河马咕嘟 | 来源:发表于2021-03-25 16:58 被阅读0次

    Swift 可以导入 C C++ object C (c的超级) cocoa ( object C 框架)Swift 是一个区分大小写的语言,所以字母大写与小写是不一样的。
    类型安全 :运行时会检测到不同类型的赋值会标记报错; Let 常量 Var 变量
    import Cocoa

    var varA = 42
    varA = "This is hello"
    print(varA)类型推断: 根据后面的赋值推断当前变量的类型 let meaningOfLife = 42
    // meaningOfLife 会被推测为 Int 类型
    变量输出:反斜杠加括号来插入变量print("(name)的官网地址为:(site)")Swift 可选(Optionals)类型: Optional 是一个含有两种情况的枚举,None 和 Some(T),,用来表示可能有或可能没有值var optionalInteger: Int?
    var optionalInteger: Optional<Int>

    var num:String?
    var num:Optional<Double>强制解析:swift “!” (解包) ,当可选类型为有值时不会报错,不然会报错, 可以用可选绑定,或者可选链来解包,这样不会出错;var myString:String?

    myString = "Hello, Swift!"

    if myString != nil {
    // 强制解析
    print( myString! )
    }else{
    print("myString 值为 nil")
    }

    自动解析
    你可以在声明可选变量时使用感叹号(!)替换问号(?)。这样可选变量在使用时就不需要再加一个感叹号(!)来获取值,它会自动解析。
    var myString:String!

    myString = "Hello, Swift!"

    if myString != nil {
    print(myString)
    }else{
    print("myString 值为 nil")
    }

    可选绑定 :如果有值就把optional 赋值给 这个变量/常量; 没有值也不会运行报错
    if let constantName = someOptional {
    statements
    }

    可选链 : 注意这里有个“问号”,这就是可选链:在“问号”后的所有代码,只会在“问号”前的代码有值时,才会运行。这不会影响 album 的基本数据类型,因为无论这行返回 nil 还是大写的 album 名称,它都是一个可选 string 。

    let album = albumReleased(year: 2006)?.uppercased()
    print("The album is (album)")

    nil 合并运算符 “?? “:它起的作用就好像你会说“如果可以的话,使用 A 的值,如果 A 是 nil 的话就使用 B 的值。

    let num = A ?? B

    Swift 字面量 :就是指像特定的数字,字符串或者是布尔值这样,能够直接了当地指出自己的类型并为变量进行赋值的值

    定义枚举

    enum name {
    case Sunday
    case Monday
    case TUESDAY
    case WEDNESDAY
    case THURSDAY
    case FRIDAY
    case Saturday
    }

    var user = name.Sunday

    user = .TUESDAY

    switch user {

    case .Sunday:
    print("星期天")
    case .Monday:
    print("星期一")
    case .TUESDAY:
    print("星期二")
    case .WEDNESDAY:
    print("星期三")
    case .THURSDAY:
    print("星期四")
    case .FRIDAY:
    print("星期五")
    case .Saturday:
    print("星期六")

    }

    枚举相关值

    enum Student{
    case Name(String)
    case Mark(Int,Int,Int)
    }
    var studDetails = Student.Name("Runoob")
    var studMarks = Student.Mark(98,97,95)

    switch studMarks {
    case .Name(let studName):
    print("学生的名字是: (studName)。")
    case .Mark(let Mark1, let Mark2, let Mark3):
    print("学生的成绩是: (Mark1),(Mark2),(Mark3)。")
    }

    枚举原始值
    原始值可以是字符串,字符,或者任何整型值或浮点型值。每个原始值在它的枚举声明中必须是唯一的。
    在原始值为整数的枚举时,不需要显式的为每一个成员赋值,Swift会自动为你赋值。

    enum Month: Int {
    case January = 1, February, March, April, May, June, July, August, September, October, November, December
    }

    let yearMonth = Month.May.rawValue
    print("数字月份为: (yearMonth)。")数字月份为:5

    结构体应用 :结构体实例总是通过值传递来定义你的自定义数据类型。

    •   结构体的主要目的是用来封装少量相关简单数据值。
      
    •   有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用。
      
    •   任何在结构体中储存的值类型属性,也将会被拷贝,而不是被引用。
      
    •   结构体不需要去继承另一个已存在类型的属性或者行为。
      

    值传递: 赋值的时候,传递的是复制的值 ,修改前一个或者后一个对另外一个的值不受影响. 结构体 枚举 值面变量

    func test() {
    var age = 18

    var age2 = age
    
    age = 20
    
    age2 = 30
    
    print("age:\(age)--age2:\(age2)")
    

    }

    test()

    引用传递 : 传递的时候赋值给的是前一个实例的地址,前后拥有是同一个地址,修改任何一个都会影响前一个.
    Class 省略1,结构体的函数中需要修改自身的属性,需要使用mutating修饰函数,而类不需要
    2,mutating的本质就是给隐式参数self用inout修饰
    3,inout修饰的参数是使用地址的,不是值传递,是引用
    4,mutating修饰的是函数,inout修饰的是参数

    因为类是引用类型,有可能有多个常量和变量在后台同时引用某一个类实例。
    为了能够判定两个常量或者变量是否引用同一个类实例,Swift 内建了两个恒等运算符:

    恒等运算符 ===

    如果两个变量 引用同一个实例,返回true

    不恒等运算符 !==

    如果两个变量 引用不同实例,返回true

    class SampleClass: Equatable {
    let myProperty: String
    init(s: String) {
    myProperty = s
    }
    }
    func ==(lhs: SampleClass, rhs: SampleClass) -> Bool {
    return lhs.myProperty == rhs.myProperty
    }

    let spClass1 = SampleClass(s: "Hello")
    let spClass2 = SampleClass(s: "Hello")

    if spClass1 === spClass2 {// false
    print("引用相同的类实例 (spClass1)")
    }

    if spClass1 !== spClass2 {// true
    print("引用不相同的类实例 (spClass2)")
    }

    引用不相同的类实例 SampleClass

    Lazy: 延迟存储属性 ,第一次调用时,才会计算存储值的属性延迟存储属性一般用于:
    延迟对象的创建。
    当属性的值依赖于其他未知类

    class sample {
    lazy var no = number() // var 关键字是必须的
    }

    class number {
    var name = "Runoob Swift 教程"
    }

    var firstsample = sample()
    print(firstsample.no.name)
    属性观察器 swift 的伟大之处

    willSet 属性被设置之前
    didSet属性被设置之后调用
    willSet和didSet观察器在属性初始化过程中不会被调用

    class Samplepgm {
    var counter: Int = 0{
    willSet(newTotal){
    print("计数器: (newTotal)")
    }
    didSet{
    if counter > oldValue {
    print("新增数 (counter - oldValue)")
    }
    }
    }
    }
    let NewCounter = Samplepgm()
    NewCounter.counter = 100
    NewCounter.counter = 800
    类型属性
    static 关键字 static 来定义值类型的类型属性,类似于实例的属性,类型属性的访问也是通过点运算符(.)来进行。但是,类型属性是通过类型本身来获取和设置,而不是通过实例。实例如下:

    struct StudMarks {
    static let markCount = 97
    static var totalCount = 0
    var InternalMarks: Int = 0 {
    didSet {
    if InternalMarks > StudMarks.markCount {
    InternalMarks = StudMarks.markCount
    }
    if InternalMarks > StudMarks.totalCount {
    StudMarks.totalCount = InternalMarks
    }
    }
    }
    }

    var stud1Mark1 = StudMarks()
    var stud1Mark2 = StudMarks()

    stud1Mark1.InternalMarks = 98
    print(stud1Mark1.InternalMarks)

    stud1Mark2.InternalMarks = 87
    print(stud1Mark2.InternalMarks)

    关键字 final 防止类型被重写 Overriding 枚举类型的可失败构造器

    enum TemperatureUnit {
    // 开尔文,摄氏,华氏
    case Kelvin, Celsius, Fahrenheit
    init?(symbol: Character) {
    switch symbol {
    case "K":
    self = .Kelvin
    case "C":
    self = .Celsius
    case "F":
    self = .Fahrenheit
    default:
    return nil
    }
    }
    }

    let fahrenheitUnit = TemperatureUnit(symbol: "F")
    if fahrenheitUnit != nil {
    print("这是一个已定义的温度单位,所以初始化成功。")
    }

    let unknownUnit = TemperatureUnit(symbol: "X")
    if unknownUnit == nil {
    print("这不是一个已定义的温度单位,所以初始化失败。")
    }

    析构 一般会自己释放,但是自己操作资源的文件,需要在类释放之前释放

    deinit {
    // 执行析构过程
    }

    例如,如果创建了一个自定义的类来打开一个文件,并写入一些数据,你可能需要在类实例被释放之前关闭该文件。

    弱引用和无主引用

    当闭包和捕获的实例总是互相引用时并且总是同时销毁时,将闭包内的捕获定义为无主引用。

    相反的,当捕获引用有时可能会是nil时,将闭包内的捕获定义为弱引用。
    如果捕获的引用绝对不会置为nil,应该用无主引用,而不是弱引用。class HTMLElement {

    let name: String
    let text: String?
    
    lazy var asHTML: () -> String = {
        [unowned self] in
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        } else {
            return "<\(self.name) />"
        }
    }
    
    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }
    
    deinit {
        print("\(name) 被析构")
    }
    

    }

    //创建并打印HTMLElement实例
    var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
    print(paragraph!.asHTML())

    // HTMLElement实例将会被销毁,并能看到它的析构函数打印出的消息
    paragraph = nil

    Swift 类型转换

    wift 语言类型转换可以判断实例的类型。也可以用于检测实例类型是否属于其父类或者子类的实例。

    Swift 中类型转换使用 is 和 as 操作符实现,is 用于检测值的类型,as 用于转换类型。
    类型转换也可以用来检查一个类是否实现了某个协议。

    Swift 访问控制

    public 可以访问模块中任何实体,别人也可以通过引用该模块来访问
    internal 可以访问自己模块中的任何实体,但是别人不能访问模块中源文件的实体 (默认)
    fileprivate 文件内私有,只能在当前源文件中使用。
    private 只能在类中访问,离开了这个类或者结构体的作用域外面就无法访问。

    public 为最高级访问级别,private 为最低级访问级别。

    枚举类型访问权限
    枚举中成员的访问级别继承自该枚举,你不能为枚举中的成员单独申明不同的访问级别。

    子类访问权限
    子类的访问级别不得高于父类的访问级别。比如说,父类的访问级别是internal,子类的访问级别就不能申明为public。

    相关文章

      网友评论

          本文标题:2021 Swift 面试基础复习回顾

          本文链接:https://www.haomeiwen.com/subject/ixrrhltx.html