Swift-27-类的初始化与销毁

news2024/10/6 18:26:51

Swift的初始化是一个有大量规则的固定过程。初始化是设置类型实例的操作,包括给每个存储属性初始值,以及一些其他准备工作。完成这个过程后,实例就可以使用了。 简单来讲就是类的构造函数,基本语法如下:

注意:初始化不仅只针对类,也对结构体有效。类和结构体通用
在这里插入图片描述

对象初始化函数定义

类的初始化

init是关键字,参数个数0~N个,这个是和Objective-C语言是有点不太一样的。

 class CustomType {
    init(someValue: SomeType) { //init是关键字,参数个数0~N个
        // 初始化代码
    }
}

如果不显示声明初始化函数的话,默认为init(){}。

结构体初始化

默认初始化函数

swift为结构体提供了两种默认的构造函数,一种是空属性的,另一种是全属性的。所以像下面的代码两种调用方式都可以。

//Town.swift
struct Town { //定义了一个名为Town的结构体
    //定义了两个属性
    var population = 5422
    var numberOfStoplights = 4
    
    //定义实例方法
    func printDescription() {
        print("Population: \(population); number of stop lights: \(numberOfStoplights)")
    }
    
    //定义修改方法,需要添加mutating关键字
    mutating func changePopulation(by amount: Int) {
        population += amount
    }
}

测试代码

var town = Town()
var town = Town(population:10000, numberOfStoplights:10)

自定义初始化函数

如果自定义了构造函数,上述两种默认构造函数就全不能用了。

struct Town {
    //因为删除了默认值,所以不能和自动类型识别了,需要手动指定属性类型
    let region: String
    var numberOfStoplights: Int
    var population: Int {
        didSet(oldPopulation) {
            print("The population has changed to \(population) from \(oldPopulation).")
        }
    }
    
    /*下面是自定义的初始化方法,这里的?号表示可失败的初始化方法也可以用!号来代替,也可以不写
    1.可失败的意思一般用于参数检查,如果检查失败则返回一个nil值。然后在程序调用时也用myTown?这种方式调用,会更安全;
    2. guard 就是一个关键字,用于确保可以提前返回
    */
    init?(region: String, population: Int, stoplights: Int) {
    
        //可失败就体现在这里,参数如果不合适,则直接返回nil(创建失改),这种特性比较好用,在其它语言中一种会用抛异常的方式或工厂的方式来实现。
        guard population > 0 else {
            return nil
        }
        self.region = region
        self.population = population
        numberOfStoplights = stoplights
    }
    
    //初始化方法2:N/A表示空字符串值传入
    init?(population: Int, stoplights: Int) {
        self.init(region: "N/A", population: population, stoplights: stoplights)
    }
    
    var townSize: Size {
        get {
            precondition(self.population >= 0, "Town cannot have negative population.")
            switch self.population {
            case 0...10_000:
                return Size.small
                
            case 10_001...100_000:
                return Size.medium
                
            default:
                return Size.large
            }
        }
    }
    
    enum Size {
        case small
        case medium
        case large
    }
    
    func printDescription() {
        print("Population: \(population); number of stop lights: \(numberOfStoplights); region: \(region)")
    }
    mutating func changePopulation(_ amount: Int) {
        population += amount
    }
}

测试调用

var myTown = Town(population: 5, stoplights: 4)
myTown?.printDescription()

let ts = myTown?.townSize
print(ts) //Optional(swiftcommandtool.Town.Size.small)

对象初始化

类的初始化需要注意继承的问题,默认时类只会提供一个空的构造函数方法,这是和结构体不一样的地方

  1. 指定初始化方法,用于给类的所有属性设置初始值;程序代码没有任何修饰关键字,可以有多个;
  2. 便捷初始化方法,只是一种标识,一般会委托给指定初始化方法来实现;用关键字convenience修饰,可以有多个;
  3. 类的必需初始化方法,一个类要求其子类必须提供特定的初始化方法;
  4. 反初始化方法,在类的实例销毁时执行内存清理过程;用deinit定义,一个类只能有一个此方法

因为默认的初始化方法必须给所有属性设置初始值,则便捷初始化方法则不需要。

默认初始化方法

类的默认初始化方法也是int(){},与结构体不同,类没有默认的成员初始化方法。这解释了为什么之前要给类设置默认值:这样可以利用自带的空初始化方法。比如:let fredTheZombie = Zombie(),其中的空圆括号表示这是一个默认初始化方法。

自定义构造函数

父类

class Monster {
    var town: Town?
    var name: String
    
    var victimPool: Int {
        get {
            return town?.population ?? 0
        }
        set(newVictimPool) {
            town?.population = newVictimPool
        }
    }
    
    //自定义的初始化方法, required 表示所有子类都必须实现此构造方法,否则程序会报错
    required init(town: Town?, monsterName: String) {
        self.town = town
        name = monsterName
    }
    
    func terrorizeTown() {
        if town != nil {
            print("\(name) is terrorizing a town!")
        } else {
            print("\(name) hasn't found a town to terrorize yet...")
        }
    }
}

子类

默认情况下子类不会自动继承父类的初始化方法,目的是希望避免子类在不经意间提供了无法为所有属性赋值的初始化方法,但在下列两种场景中子类会继承父类的初始化方法:

  1. 子类没有定义任何自定义的初始化方法;
  2. 如果子类复写了父类所有指定的初始化方法,也会继承父类的所有便捷初始化方法;
class Zombie: Monster {
    class var spookyNoise: String {
        return "Brains..."
    }
    
    var walksWithLimp: Bool
    private(set) var isFallingApart: Bool
    
    //子类特有的初始化方法
    init(limp: Bool, fallingApart: Bool, town: Town?, monsterName: String) {
        walksWithLimp = limp
        isFallingApart = fallingApart
        super.init(town: town, monsterName: monsterName)
    }
    
    //convenience 关键字用来表示快捷初始化方法
    convenience init(limp: Bool, fallingApart: Bool) {
        self.init(limp: limp, fallingApart: fallingApart, town: nil, monsterName: "Fred")
        if walksWithLimp {
            print("This zombie has a bad knee.")
        }
    }

   //复写父类的初始化方法,可以省略overrid关键字
    required init(town: Town?, monsterName: String) {
        walksWithLimp = false
        isFallingApart = false
        super.init(town: town, monsterName: monsterName) //调用父类构造函数
    }
    
    final override func terrorizeTown() {
        if !isFallingApart {
            town?.changePopulation(-10)
        }
    }

}

程序调用

//调用Zombie指定初始化方法:init(limp: Bool, fallingApart: Bool, town: Town?, monsterName: String) 
//The population has changed to 999995 from 1000005.
//Population: 999995; number of stop lights: 4; region: N/A
var fredTheZombie: Zombie? = Zombie(limp: false, fallingApart: false, town: myTown, monsterName: "Fred")
fredTheZombie?.terrorizeTown()
fredTheZombie?.town?.printDescription()

//调用快捷初始化方法:convenience init(limp: Bool, fallingApart: Bool)
//This zombie has a bad knee.
var convenientZombie = Zombie(limp: true, fallingApart: false)

//Victim pool: Optional(999995)
//The population has changed to 500 from 999995.
//Victim pool: Optional(500)
print("Victim pool: \(fredTheZombie?.victimPool)")
fredTheZombie?.victimPool = 500
print("Victim pool: \(fredTheZombie?.victimPool)")

//调用反初始化方法
//Brains...
//Zombie named Fred is no longer with us.
print(Zombie.spookyNoise)
fredTheZombie = nil

初始化函数参数

初始化的函数参数也和普通函数一样,支持内、外名称加类型这种,也支持一些特殊特性,比如下面的_用法,隐藏外部参数名称。

struct WeightRecordInLBS {
    let weight: Double
    
    //用_来指定
    init(_ pounds: Double) {
        weight = pounds
    }
    init(kilograms kilos: Double) {
        weight = kilos * 2.20462
    } 
}

//
let wr = WeightRecordInLBS(185)

对象的销毁(反向初始化)

反初始化(deinitialization)是在类的实例没用之后将其清除出内存的过程。从概念上讲,反初始化就是初始化的反面。只有引用类型可以反初始化,值类型不行。 在Swift中,实例被清除出内存之前会调用反初始化方法。这提供了销毁实例前最后做一些维 护工作的机会。

    deinit {
        print("Zombie named \(name) is no longer with us.")
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1619108.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3节点ubuntu24.04服务器docker-compose方式部署高可用elk+kafka日志系统并接入nginx日志

一:系统版本: 二:部署环境: 节点名称 IP 部署组件及版本 配置文件路径 机器CPU 机器内存 机器存储 Log-001 10.10.100.1 zookeeper:3.4.13 kafka:2.8.1 elasticsearch:7.7.0 logstash:7.7.0 kibana:7.7.0 zookeeper:/data/zookeep…

贪心算法在单位时间任务调度问题中的应用

贪心算法在单位时间任务调度问题中的应用 一、引言二、问题描述与算法设计三、算法证明四、算法实现与效率分析五、C语言实现示例六、结论 一、引言 单位时间任务调度问题是一类经典的优化问题,旨在分配任务到不同的时间槽中,使得某种性能指标达到最优。…

【JAVA】UDP与TCP套接字编程

目录 一、UDP数据报套接字编程 1、DatagramSocket API 2、DatagramPacket API 3、InetSocketAddress API 4、示例一 5、示例二 二、TCP流套接字编程 1、ServerSocket API 2、Socket API 3、TCP中的长短连接 4、示例一 5、示例二 一、UDP数据报套接字编程 1、Datag…

《ElementPlus 与 ElementUI 差异集合》el-select 显示下拉列表在 Cesium 场景中无法监听关闭

前言 仅在 Element UI 时有此问题,Element Plus 由于内部结构差异较大,不存在此问题。详见《el-select 差异点,如:高、宽、body插入等》; 问题 点击空白处,下拉列表可监听并关闭;但在 Cesium…

图解《图搜索算法》及代码实现

关注我,持续分享逻辑思维&管理思维; 可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导; 有意找工作的同学,请参考博主的原创:《面试官心得--面试前应该如何准备》,《面试官心得--面试时如何进行自…

Jmeter之Beanshell详解

一、 Beanshell概念 Beanshell: BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;BeanShell是一种松散类型的脚本语言(这点和JS类似);BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性…

LayuiMini使用时候初始化模板修改(下载源码)

忘记加了 下载 地址 : layui-mini: layuimini,后台admin前端模板,基于 layui 编写的最简洁、易用的后台框架模板。只需提供一个接口就直接初始化整个框架,无需复杂操作。 LayuiMini使用时候初始化模板官网给的是: layu…

用Excel做一个功能完备的仓库管理系统

1 基本设计思路 用到的Excel技术:sumif, vlookup, 表格(table)。基本思路:在有基础的商品、仓库等信息的情况下,对商品的每一个操作都有对应的单据,然后再汇总统计。标识:为了在不同的维度统计数量,各单据…

国产FTP文件传输服务器需要具备哪些关键特性?

国产FTP文件传输服务器是指根据中国国内信息技术创新(信创)的要求和标准,自主研发的文件传输服务器软件。这类软件旨在替代传统的FTP服务器,以更好地适应国产化和信息安全的需要。国产FTP文件传输服务器通常需要具备以下要求&…

图书租赁系统-扣费服务

resources中添加moment.js文件。 然后引入moment.js文件&#xff1a; <script src"/js/moment.js"></script>借阅结束时间选完后changeDate事件&#xff1a; $("input[nameendTime]").datetimepicker({format: "yyyy-mm-dd hh:ii",…

Linux:进程与计划任务

文章目录 Linux&#xff1a;进程与计划任务一、进程1、进程是什么2、进程状态 二、列出进程命令1、查看静态的进程统计信息——“ps”Play1&#xff1a;“ps aux”Play2:ps -elf 2、查看静态的进程统计信息——“top”段首解析进程信息区解释 三、运行与终止进程3.1、运行进程3…

为什么要写技术方案?

技术方案是为研究解决各类技术问题&#xff0c;有针对性&#xff0c;系统性的提出的方法、应对措施及相关对策。技术方案设计是一个技术开发者必备的能力&#xff0c;特别是对于高级、资深、架构师等角色。技术方案设计不仅能够帮助我们明确需求&#xff0c;规划架构&#xff0…

2024新算法爱情进化算法(LEA)和经典灰狼优化器(GWO)进行无人机三维路径规划设计实验

简介&#xff1a; 2024新算法爱情进化算法&#xff08;LEA&#xff09;和经典灰狼优化器&#xff08;GWO&#xff09;进行无人机三维路径规划设计实验。 无人机三维路径规划的重要意义在于确保飞行安全、优化飞行路线以节省时间和能源消耗&#xff0c;并使无人机能够适应复杂环…

windows系统下python开发工具安装

一. 简介 前一篇文章学习了安装 python解释器&#xff0c;文章如下&#xff1a; windows系统下python解释器安装-CSDN博客 本文来学习如何下载安装 python开发工具 PyCharm。 二. python开发工具 PyCharm下载安装 1. PyCharm官网 PyCharm开发工具 PyCharm为 python代码…

STM32的GPIO输入和输出函数详解

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. GPIO模式 2. GPIO输出 2.1 RCC 2.2 GPIO 3. 代码示例 3.1 RCC时钟 3.2 GPIO初始化 3.3 GPIO输出函数 3.4 推挽输出和开漏输出 4. GPIO输入 4.1 输入模式 4.2 数据读取函数 5. C语言语法 1…

Mudem,打造私密安全、高效稳定的私人空间

Mudem 是 Codigger 平台中的一个关键组件&#xff0c;它提供基础通讯服务&#xff0c;确保不同类型的机器之间可以进行安全和高效的连接。它其设计理念在于将本地机器、公有云以及私有云上的设备无缝地整合为一个可远程在线访问的工作站&#xff08;Workstation&#xff09;。这…

Android SDK Manager安装Google Play Intel x86 Atom_64 System Image依赖问题

Package Google Play Intel x86 Atom_64 System Image,Android API R, revision 2 depends on SDK Platform Android R Preview, revision 2 问题 一开始以为网络还有依赖包没有勾选&#xff0c;尝试了很多次&#xff0c;勾选这边报错对应的license即可。此时点击一下其他licen…

【LeetCode】---118.杨辉三角

一、题目解析&#xff1a; 二、知识回顾&#xff1a; 1.二维数组&#xff1a; 2. C语言中的二维数组访问方式和vector二维数组的访问&#xff0c; 不同区别&#xff1a; &#xff08;1&#xff09;表面是一样的&#xff0c;但底层不同&#xff01; &#xff08;2&#xff09;静…

“PowerInfer:消费级GPU上的高效大语言模型推理引擎“

PowerInfer是由上海交通大学IPADS实验室开发的一个高效大语言模型&#xff08;LLM&#xff09;推理引擎&#xff0c;专为个人电脑&#xff08;PC&#xff09;上的消费者级GPU设计。它通过利用LLM推理中的高局部性&#xff0c;实现了快速且资源消耗低的模型推理&#xff0c;这一…

【插件】IDEA 热部署插件 JRebel

1 搜索安装插件 JRebel 2 选中Team URL 1、在上面的框中输入激活的url地址 https://jrebel.qekang.com/{GUID} http://jrebel-license.jiweichengzhu.com/{GUID} GUID生成工具 Create GUID online (guidgen.com) 备用 404 Not Found (ofmonkey.com) 如果上述激活地址不能…