• init()和deinit()


    一、初始化方法(init()) 
    1、定义:类初始化对象时所调用的方法 
    2、分类: (1)默认初始化方法 
    (2)便利初始化方法 
    (3)使用闭包 
    3、一些注意点: 
    (1)方法固定名为init,没有返回值,方法名init前面也不需要加func 
    (2)在创建对象之后,如果要使用对象的属性之前,必须对属性初始化 
    (3)声明一个变量,必须赋初始值,除非这个变量是强制解包可选,或者在初始化方法赋初始值,也可达到同样的效果 
    (4)初始化方法可以多个存在,并且每一个的方法名都是init,但是参数要不同。对于方法参数不同,不仅仅通过参数类型来判断,还涉及参数的名称,这个在其他语言中称为:方法的重载(参数名或者参数别名不同) 
    4、一些例子的运用代码块

    4.1、默认初始化方法,声明成员属性的时候,不赋初始值,但必须要有初始话方法对成员变量进行初始化 
    这里写图片描述

    4.2、当声明为强制解包可选(!)可以不用初始化方法,在类进行实例化对象的时候再对变量进行赋初始值,但是有也没关系。 
    这里写图片描述

    4.3、多个初始化方法并行(方法的重载) 
    这里写图片描述

    4.4、初始化方法的分类 
    (1) 使用提供的默认初始化方法 
    这里写图片描述

    (2)便利初始化方法及其重载 
    这里写图片描述

    (3)使用闭包(如果某个存储属性的默认值需要特别定制或者准备,那么久可以使用闭包来初始化这个属性的默认值) 
    这里写图片描述

    二、反初始化方法(deinit()) 
    1、定义:可以这么理解,初始化方法是为了类创建对象的时候,使用对象属性对其属性赋初始值,那么当你这个对象销毁的使用,也要对气属性进行释放。构造那么一个场景:当我们建立一个数据库访问,在初始化的时候打开链接,如果程序退出,链接不释放,资源就浪费了,反初始化方法可以释放这个链接,减少资源浪费。 
    2、注意点 
    当要关闭链接的时候,要把对象设置为nil,不然反初始化方法不会被调用 
    3、暂时没找到比较好的例子可以说明,后面会介绍。

    析构器只适用于类类型,当一个类的实例被释放之前,析构器会被立即调用。析构器用关键字deinit来标识,类似于构造器用init来标识。

      

      原理:

      Swift会自动释放不再需要的实例以释放资源。Swift通过自动引用计数ARC处理实例的内存管理。通常当你的实例被释放时,不需要手动地 进行清理。但是,当使用自己的资源时,你可能需要进行一些额外的清理。例如:如果创建了一个自定义的类来打开一个文件,并写入一些数据,你可能需要在类实 例被释放之前手动去关闭该文件。

      在类的定义中,每个类最多只能有一个析构器,而且析构器不带任何参数:

    1
    2
    3
    deinit{
    //执行析构过程
    }

      析构器在实例释放之前被自动调用,析构器是不允许被主动调用的。子类继承了父类的析构器,并且在子类析构器实现的最后,父类的析构器会被自动调用。即使子类没有提供自己的析构器,父类的析构器也同样会被调用。

      因为知道实例的析构器被调用时,实例才会被释放。所以析构器可以访问所有请求实例的属性,并且根据那些属性可以修改它的行为。比如查找一个需要被关闭的文件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    struct Bank {
        static var coinsInBank 10000
        static func vendCoins(var numberOfCoinsToVendInt) -> Int{
            numberOfCoinsToVend min(numberOfCoinsToVend,coinsInBank)
            coinsInBank -= numberOfCoinsToVend
            return numberOfCoinsToVend
        }
         
        static func receiveCoins(coins:Int){
            coinsInBank += coins
        }
    }
     
    class Player {
        var coinsInPurse:Int
        init(coins:Int){
            coinsInPurse Bank.vendCoins(coins)
        }
         
        func winCoins(coins:Int){
            coinsInPurse += Bank.vendCoins(coins)
        }
         
        deinit{
            Bank.receiveCoins(coinsInPurse)
        }
    }
     
    var playerOne:Player? = Player(coins100)
    print(playerOne!.coinsInPurse)
     
    print(Bank.coinsInBank)
     
    playerOne!.winCoins(1000)
    print(playerOne!.coinsInPurse)
     
    print(Bank.coinsInBank)
    playerOne nil
     
    print(Bank.coinsInBank)
     
    100
    9900
    1100
    8900
    10000

      playerOne是可选的,所以要用一个感叹号!来做修饰符。

      当playerOne是nil时,意思是不存在Player实例,当这种情况发生时,playerOne变量对Player实例的引用被破坏 了。没有其他属性或者变量引用Player实例,因此为了清空它占用的内存从而释放它。在这发生前,其析构器会被自动调用,从而使其硬币被返回到bank 对象中。

  • 相关阅读:
    关于web前端网站优化
    C/S与B/S架构的区别和优缺点
    什么是闭包?闭包的优缺点?
    JavaScript中基本数据类型和引用数据类型的区别
    jQuery对象与DOM对象之间的转换方法
    (转)第05节:Fabric.js的动画设置
    (转)第04节:Fabric.js用路径画不规则图形
    layui表单与原生js表单的一些小问题(三)
    layui表单与原生js表单的一些小问题(二)
    layui表单与原生js表单的一些小问题(一)
  • 原文地址:https://www.cnblogs.com/zhuyeshen/p/11788322.html
Copyright © 2020-2023  润新知