Tags: Swift 学习笔记

发布时间:2015-08-04
修改时间:2015-08-04
作者:Erwin
博客地址:技术杂货铺
欢迎转载,转载请注明出处。

Swift学习笔记系列——(13)初始化

初始化

目标:类、结构体和枚举
目的:实例使用前的准备,存储属性赋值以及其他必要操作

给存储属性初始值

类和结构体的存储属性在使用前必须要有初始值,提供初始值可以通过定义时指定,也可以通过构造方法赋值。
初始化过程中给存储属性赋值,不会触发观察者行为。

自定义初始化

通过构造方法的参数给必须要有值的存储属性赋值、给可选类型属性赋值;
初始化过程中给常量属性赋值;

构造方法的参数语法和函数以及方法的相同。
在初始化阶段中的任意时刻,都可以给常量属性赋值,但是一旦赋值就不能修改了。

默认构造方法

如果结构体和类中所有的属性都有默认值了,尽管没有明确声明,但实际上已经有了一个不需要参数的默认构造方法。

结构体的额外特权(Memberwise Initializers for Structure Types)

即使没有给全部属性度提供默认值,结构体仍会自动获得一个构造方法(Memberwise Initializers)。
这个构造方法以结构体成员名字作参数,会给其中的成员赋值。

值类型的初始化代理

构造方法可以调用其它构造方法来实现一个实例初始化的一部分。这个过程,叫做构造方法代理(initializer delegation),这样做避免了在多个构造方法中出现重复代码。

构造方法代理的工作规则和什么形式的代理是被允许的,这些对于值类型和类类型而言是不相同的。

对于值类型,采用selft.init引用其他构造方法即可。
需要注意如果值类型定义了构造方法,就不能再访问它的默认构造方法了(或者Memberwise Initializers,当值类型是结构体的时候)。这是为了避免意外使用默认构造方法,而没有使用提供了必要操作的稍微复杂的自定义构造方法。

对于值类型,如果想在自定义的构造方法中引用自动获得的构造方法,那么把自定义构造方法写在扩展中。

类的继承和初始化

继承是类的特有行为,类的初始化要保证类的所有属性都被赋值,不论是继承来的还是自身定义的。

类的初始化通过两种构造方法实现:指定构造方法和方便构造方法

指定构造方法

必须要有,可以有多个,但一般是一个,是继承链上的一部分,子类的指定构造方法会调用超类的构造方法。

方便构造方法

不是必须的,必须要引用同一个类的指定构造方法,可以有多个。定义的时候需要用关键字“convenience ”特别强调。

构造方法调用其他构造方法的规则

指定构造方法必须调用它的直接超类的一个指定构造方法。
方便方法必须调用同一个类的另外一个构造方法。
方便方法必须最终调用到一个指定构造方法。

指定构造方法总是被委托方;
方便构造方法总是委托方。

初始化的两个阶段

这部分主要要说明类的初始化顺序。
顺序是这样的:

https://www.processon.com/view/link/55bb389be4b0f902d22391f7

第二阶段开始才可以访问实例方法和self。

构造方法的继承和重写

子类不默认继承超类的构造方法。
子类用override关键字定义重写的构造方法。
根据类构造方法引用的规则,子类不可能重写超类的方便构造方法,只能重写超类的指定构造方法。

构造方法自动继承

子类新加的属性都有默认值的前提下:
如果子类没有定义任何指定构造方法,则默认继承超类的指定构造方法。
如果子类有超类所有指定构造方法的实现,无论是通过继承还是通过重写,那么子类会默认继承超类的全部方便构造方法。

可失败构造方法

init?
不能定义拥有相同参数类型和名称的可以失败的和不可失败的构造方法。

枚举

可以定义失败的构造方法,根据参数选择是否能构造出一个成员。

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
        }
    }
}

枚举自动获得的可以失败构造方法

获得条件:枚举成员有原始值
形式:init?(rawValue:)

类的可以失败的构造方法

值类型的可失败构造方法可以在构造方法的任意时刻出发构造失败,但是对于类就不行了。类的构造方法要出发构造失败,需要在自身的所有存储属性被赋值了初始值而且调用了其他构造方法之后才能进行。

可以失败构造方法的传递

可以失败构造方法可以调用不可失败构造方法,但这样会导致构造结果的不确定性。
不可失败构造方法不可以调用可以失败构造方法。因为这样构造结果的确定性就未知了。
继承链上的构造方法失败后,后续初始化操作不再继续执行。

重写可以失败的构造方法

可失败的构造方法可以被重写为不可失败的构造方法,但不能再引用超类的可失败构造方法了。
不可失败的构造方法不可以被重写为可失败的构造方法。

init!可失败构造方法

init!和init?可以相互调用,相互重写。

必须构造方法

required修饰符标记的构造方法叫必须构造方法,所有子类必须要有。
必须构造方法有传递性,子类的子类也要有。
通过继承就获得了的,不必提供实现。
重写了一个必须构造方法,不必用override关键字,只用required关键字就行了。

通过闭包和函数给属性设置默认值

可以用闭包和函数给属性设置默认值
用闭包给属性设置值的时候要注意,此时初始化尚未完成,不能访问实例属性和self。

几种构造方法释义

分类依据 名称 标记和说明
是否在继承链上 指定构造方法
方便构造方法 convenience
是否构造成功 不可失败构造方法
可失败构造方法 init?或者init!
子类是否构一定要实现 一般构造方法
必须构造方法 required
子类是否构重写 一般构造方法
重写构造方法 override
自动获得的构造方法 类和结构体的无参数构造方法 条件:属性都有默认值而且没有定义构造方法
结构体的初始化成员构造方法 条件:没有定义构造方法
枚举自动获得的可失败构造方法 init?(rawValue:)
类自动继承的指定构造方法 条件:新加属性有默认值而且没有定义指定构造方法
类自动继承超类所有方便构造方法 条件:新加属性有默认值而且有超类所有的指定构造方法实现

本章思维导图

Swift学习笔记系列——13初始化的更多相关文章

  1. three.js模拟实现太阳系行星体系功能

    这篇文章主要介绍了three.js模拟实现太阳系行星体系功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

  2. HTML5页面无缝闪开的问题及解决方案

    这篇文章主要介绍了HTML5页面无缝闪开方案,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. iOS >>块>>更改块外部的变量值

    我不是在处理一个Object并改变它,就像我的mString一样.我希望’center’属性的行为类似于myInt,因为它是直接访问的C结构,而不是指向对象的指针.我希望’backgroundColor’的行为类似于我的imstring,因为它是一个指向一个新对象的对象的指针,不是吗?

  4. ios – 为什么,将nil作为参数从Objc C发送到swift类初始化器,用新对象替换nil参数

    除非属性本身被声明为nonnull:

  5. ios – 在Swift中对MKCircle进行子类化

    我想通过添加另一个String属性来继承MKCircle,我们称之为“代码”.这个属性不是可选的和常量的,所以我必须从初始化器设置它,对吧?有没有办法定义一个单一的便利初始化器,在这种情况下需要3个参数?本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  6. ios – AVAudioPlayer不再使用Swift 2.0/Xcode 7 beta

    对于我的iPhone应用程序中的vartestAudio声明,我在这里收到错误“调用可以抛出,但错误不能从属性初始化程序中抛出”当我转到Xcode7测试版时,就发生了这种情况.如何在Swift2.0中使用此音频剪辑?

  7. ios – 斯威夫特.在初始化所有存储的属性之前在方法调用中使用’self’

    解决方法在初始化所有非可选实例变量之前,您无法在self上调用方法.有几种方法可以解决这个问题.>将属性更改为选项或隐式解包选项(不建议)>使buildCircle()方法静态或只是一个在文件中运行并为所有圆圈调用addSubview()在所有属性初始化并且您调用之后super.init()等等.你必须避免在自己之前打电话给自己class已初始化.

  8. ios – Objective-C警告未找到超类“-init”的指定的初始化程序的方法覆盖

    我在一个应用程序中清理警告,我收到了两次这个警告对于这行代码和这一行我相当新的Objective-C和谷歌这个警告,只是不明白的解决方案我的问题是如何摆脱这些警告?

  9. ios – UICollectionView不能使用UISearchController?

    在WWDC2014年的“AInsideInsidePresentationControllers”中,演示者展示了如何在UITableView中设置UISearchController.他们通过设置searchController的searchBar框架,然后将其设置为tableView的tableHeaderView来实现.不幸的是,UICollectionView没有相当于tableHeade

  10. ios7 – 如何使用默认的IOS映像

    嗨,我是IOS开发的新手.我知道如何在IOS应用程序中使用图像.但是我不知道如何使用默认图像,如开发者站点中提到的共享或书签图标.我想用它们我必须下载这些图像集或那些可用在xcode?

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部