美文网首页2023面试看iOS面试题
iOS最新面试题解答最全-2023-Swift

iOS最新面试题解答最全-2023-Swift

作者: MoShengLive | 来源:发表于2023-02-12 10:24 被阅读0次

    一、Swift 存储属性和计算属性比较:

    存储型属性:用于存储一个常量或者变量
    计算型属性: 计算性属性不直接存储值,而是用 get / set 来取值 和 赋值,可以操作其他属性的变化.

    • 计算属性可以用于类、结构体和枚举,存储属性只能用于类和结构体。
    • 存储属性可以是变量存储属性(用关键字 var 定义),也可以是常量存储属性(用关键字let定义),而计算属性只能用var定义
    • 计算属性不直接存储值,而是提供一个 getter 和一个可选的setter,来间接获取和设置其他属性或变量的值
    var age = 12
        var name = "小花"
        var kind = "法斗"
        //定义计算属性的getter方法,该方法的返回值由age、name、kind三个存储属性决定
        var petInfo:String{
             get {
                    return "this is a pet which name is \(name),age is \(age), kind is      \(kind)"
                 }
             set (newInfo)
               {
               }
             }
    

    二、inout关键字有什么作用

    需要用到inout 关键字,调用函数时加&
    inout关键字本质是通过地址传递进行值修改的

    三、OC和Swift中的protocol

    OC和SwiftProtocol的共同点

    本质都是抽取不同类的共同方法和属性(声明),供遵循协议的类或对象使用。
    都可以通过定义协议实例deleagate,来实现委托代理模式。
    PS:类比继承的概念,继承父类的方式比较险隘,子类和父类只能为同一基类,且方法都有实现,需在子类中override,并不能把方法和属性完全独立出来,且不能多继承。

    OC和SwiftProtocol的区别(核心)

    OC中的协议更单纯的受限于委托代理的含义,多用于跨类的传值和回调通知。
    而Swift是面向协议编程,其思想是通过抽取不同类中的相同方法和属性,实现模块化减少耦合。
    Swift可以通过协议extension扩展,缺省实现协议的方法(OC不行)。
    Swift的协议不需要单独声明协议对象(id <Deleagate> delegate)和指定代理(delegate = self),只需要遵循协议的类实现声明,或使用协议的缺省实现。

    四、Swift 中的 enum 和 OC 中 有什么区别

    OC
    1.oc的枚举值相当于这个文件中的一个局部变量,只能是整型
    2.不同枚举中,枚举名称不可以一样,在同一文件
    Swift
    3.枚举里可以写方法
    4.枚举的rawValue可以是Float(float也是赋值的后面依次+1)或是String,或是没有
    5.可以用Rank(rawValue: 3)方法创建一个枚举实例
    6.枚举实例可以带参数

    五、struct和class的区别

    1)swift中所有值类型:struct、enum使用直接派发。
    2)swift中协议的extensions(类似于OC的分类)使用直接派发,初始声明函数使用函数表派发
    3)swift中class中extensions使用直接派发,初始化声明函数使用函数表派发,dynamic修饰的函数使用消息派发。

    Swift中,mutating关键字指的是可变即可修改。用在structure和enumeration中,虽然结构体和枚举可以定义自己的方法,但是默认情况下,实例方法中是不可以修改值类型的属性。为了能够在实例方法中修改属性值,可以在方法定义前添加关键字mutating。
    在 Swift 中,值类型,存放在栈区;引用类型,存放在堆区。Swift 中,典型的有 struct,enum,以及 tuple 都是值类型。
    当值类型的变量作为参数被传入函数时,相当于创建了新的常量并初始化为传入的变量值,该参数的作用域及生命周期仅存在于函数体内。
    当引用类型的变量作为参数被传入函数时,相当于创建了新的常量并初始化为传入的变量引用,当函数体内操作参数指向的数据,函数体外也受到了影响
    6.当你的项目的代码是 Swift 和 Objective-C 混合开发时,你会发现在 Objective-C 的代码里无法调用 Swift 的 Struct。因为要在 Objective-C 里调用 Swift 代码的话,对象需要继承于 NSObject。
    7.内存分配:struct分配在栈中,class分配在堆中。struct比class更“轻量级”(struct是跑车跑得快,class是SUV可以载更多的人和货物)
    3.struct是值类型(Value Type),深拷贝。class是引用类型(Reference Type),浅拷贝。

    六、Swift optional是什么类型的

    optional类型是一个枚举类型,有两个枚举值:
    1、None类型
    2、Some(Wrapped)
    这两个类型决定了optional类型的概念和含义,有值或者没有值:
    1)optional.None表示该类型没有值,也就是nil。(特别声明,swift中的nil不在有指针含义,而是表示且仅表示optional的.None)。
    2)optional.Some(Wrapped)这是表示有值的情况,Some类似于java或者c++的泛类型的含义,Wrapped 类似是封装的值。

    optional的wrap和unwrap

    使用optional类型,该类型会对赋值过程和取值进行一些处理。
    1)赋值也被称为装包的过程(wrap),optional类型会获取当前值的类型和具体值,如int类型的数字100.当一个optional类型被赋值为这个值时,其实optional记录了对应的类型(some)int,和值部分(wrapped)100.
    2)取值也被称为解包的过程(unwrap),optional根据记录的类型(some)如上面说的int,和值部分(wrapped)100,新建一个some(wrapped)同int(100)返回给程序
    optional是swift特别声明的安全类型,在使用过程中如果处理得当的话可以防止以前oc上很多因为数据没值导致的crash。个人还是比较推荐使用的,虽然有时候有些解包的过程感觉特别麻烦,但这都是一道道安全门,阻断了很多crash的诞生。

    七、rxswift中请求重试的方法是哪个?

    1,catchError

    enum ObError: Error {
        case error1
    }
    
    let ob1 = PublishSubject<String>()
    let ob2 = PublishSubject.of("A", "B")
    
    ob1.catchError { (error) -> Observable<String> in
        print(error)
        return ob2
    }.subscribe { event in
        print(event)
    }.disposed(by: disposeBag)
    ob1.onNext("111")
    ob1.onError(ObError.error1)
    //next(111)
    //error1
    //next(A)
    //next(B)
    //completed
    

    2,retry

    var isFail = true
    let obs = Observable<String>.create { (ob) -> Disposable in
        ob.onNext("成功1")
        if isFail {
            ob.onError(ObError.error1)
            isFail = false
        }
        ob.onNext("重试成功")
        ob.onCompleted()
        return Disposables.create()
    }
    
    obs.retry(2).subscribe { event in
        print(event)
    }.disposed(by: disposeBag)
    
    next(成功1)
    next(成功1)
    next(重试成功)
    completed
    

    八、讲解一下Swift中的数据封装

    封装主要有两大目的:一是为了我们使用数据更加方便,二是为了数据保护。
    1、Swift 访问修饰符
    在 Swift 语言中,访问修饰符也分为三类,分别是 private、internal、public。

    Swift 的访问修饰符从 Xcode6 beta4 才开始支持。
    Swift 对访问权限的控制,不是基于类的,而是基于文件的。
    在 Swift 语言中,若要设置某一属性的访问权限,需在定义属性时加上相应的修饰前缀。
    三类修饰符的访问权限

    1)private 所修饰的属性或者方法只能在当前 Swift 源文件里可以访问,在别的文件里访问会出错。

    2)internal 是默认的访问权限。所修饰的属性或者方法在源代码所在的整个模块都可以访问。如果是框架或者是库代码,则在整个框架内部可以访问,框架由外部代码所引用时,则不可访问。如果是 App 代码,在整个 App 内部可以访问。

    3)public 所修饰的属性或者方法对于引用了该文件或者模块的文件来讲,都能访问这些属性和方法。一般来说 public 的出现是为了 API 开发而设置。

    Class Person {
        private var _weight: Int!
    
        var weight: Int {
            get {
                return _weight
            }
            set {
                _weight = newValue
            }
        }
    }
    

    您甚至可以将变量设为公开只读,并设为私有读写:

    class Person {
        public private(set) var weight: Int
    }
    

    九、Swift异常捕捉的方法有哪些 ?

    //
    //  ViewController.swift
    //  Throws
    //
    //  Created by fe on 2017/3/7.
    //  Copyright © 2017年 fe. All rights reserved.
    //
     
    import UIKit
     
    class ViewController: UIViewController {
     
        override func viewDidLoad() {
            super.viewDidLoad()
            
            
            //如果在调用系统的方法时,后面有throws则说明此方法会抛出异常,如果方法会抛出异常,则需要我们处理异常
            
            
            //创建正则表达式规则
            let pattern = "abcdefg"
            
            //创建正则表达式队形
            /*
             在swift中提供三种处理异常的方式
                 方式一:try方式  程序员手动捕捉异常
                     do { let regex = try NSRegularExpression(pattern: pattern, options:.caseInsensitive)
                         print(regex)
                     }catch{
                         print(error)
                     }
             
                 方式二:try?方式(常用方式)  系统帮助我们处理异常,如果有异常,则该方法返回nil,如果没有异常,则该方法返回对应的对象
                     guard (try? NSRegularExpression(pattern: pattern, options: .caseInsensitive)) != nil else {
                         return
                     }
                 方式三:try!方式(不建议使用,非常危险)这种方法直接告诉系统没有异常,如果有异常则程序会崩溃
                     let regex = try! NSRegularExpression(pattern: pattern, options:.caseInsensitive)
             */
     
            
            
            
        }
     
     
    }
    
    函数中产生的异常只能在函数内部解决,开发者也可以使用throws关键字将此函数声明为可抛异常函数,此类声明则允许开发者在函数外解决函数内部抛出的异常
    

    ** 异常的捕获与处理

    系统为我们提供了三种异常处理的方法:
    
        <1> 使用do-catch结构来捕获处理异常、将异常映射为optional值,终止异常传递
    
        <2> 使用try?来调用函数可以将异常映射为Optional值
    
        <3> 使用try!来强制终止异常的传递
    
    do-catch:do-catch结构是swift语言中处理异常最常用的方法,开发者需要将可能抛出的异常的代码放入do结构中,如果这部分代码中有抛出异常,则会从catch块中寻找对应的异常类型,如果找到对应的,则会执行此catch块中的异常处理代码.
    

    十、map函数有几种、分别讲解一下?

    image.png

    高阶函数一共有下面几个:

    map:对给定数组每一个元素,执行闭包中的映射,将映射结果放置在数组中返回。
    flatMap:对给定数组的每一个元素,执行闭包中的映射,对映射结果进行合并操做,而后将合并操做后的结果放置在数组中返回。
    compactMap:对给定数组的每一个元素,执行闭包中的映射,将非空的映射结果放置在数组中返回。
    filter:对给定数组的每一个元素,执行闭包中的操做,将符合条件的元素放在数组中返回。
    reduce:对给定数组的每一个元素,执行闭包中的操做对元素进行合并,并将合并结果返回。

    相关文章

      网友评论

        本文标题:iOS最新面试题解答最全-2023-Swift

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