http://www.th7.cn/Program/IOS/201603/789227.shtml

在 OC 中 init 方法是非常不安全的,没人能够保证 init 只被调用一次,也没有人保证在初始化方法调用以后实例的各个变量都完成初始化,甚至如果在初始化里使用属性进行设置的的话,还可能会造成各种问题。Swift 强化了 designated 初始化方法的地位。swift 中不加修饰的 init 方法都需要在方法中保证所有非 Optional 得实例变量被赋值初始化,而在子类中也强制(显示或隐式的)调用 super 版本的 designated 初始化,所以无论怎样被初始化的对象总是可以完成完整的初始化的。

class ClassA {
let numA: Int
// 不加修饰的 init 方法都需要在方法中保证所有非 Optional 得实例变量被赋值初始化
init(num: Int) {
numA = num
}
} class ClassB: ClassA {
let numB: Int
override init(num: Int) {
numB = num + // 在 init 里我们可以对 let 的实例常量进行赋值,这是初始化方法的重要特点。正常情况下 let 声明的值是不可变的,无法被赋值,这对构建线程安全的 API 十分有用。而 init 只可能被调用一次,所以在 init 里我们可以为不变量进行赋值,而不会引起任何线程安全的问题
super.init(num: num)
}
}

与 designated 初始化方法啊对应的是在 init 前加上 convenience 关键字的初始化方法。这类方法只作为补充和提供使用上的方便。所有的 convenience 初始化方法都必须调用同一个类中的 designated 初始化完成设置,另外 convenience 的初始化方法是不能被子类重写或者是从子类中以 super 的方式被调用的。

class ClassAA {
let numA: Int
init(num: Int) {
numA = num
}
convenience init(bigNum: Bool) {
self.init(num: bigNum ? 10000 : 1) // 所有的 convenience 初始化方法都必须调用同一个类中的 designated 初始化完成设置
}
} class ClassBB: ClassAA {
let numB: Int
override init(num: Int) {
numB = num + 1
super.init(num: num)
}
}

只要在子类中实现重写了父类 convenience 方法所需要的 init 方法的话,我们在子类中就可以使用父类的 convenience 初始化方法了。比如上面我们即使在 ClassBB 中没有 bigNum 版本的 convenience init(bigNum: Bool),我们仍然是可以是用这个方法来完成子类初始化的:

let anObj = ClassBB(bigNum: true)
print(anObj.numA, anObj.numB)

输出:10000和10001

总结:初始化方法永远遵循以下两个原则

1.初始化路径必须保证对象完全初始化,这可以通过调用本类型的 designated 初始化方法得到保证;

2.子类的 designated 初始化方法必须调用父类的 designated 方法,以保证父类也完成初始化。

  对于某些我们希望子类中一定实现的 designated 初始化方法,我们可以通过添加 required 关键字进行限制,强制子类对这个方法重写实现。这样做的最大的好处是可以保证依赖于某个 designated 初始化方法的 convenience 一直可以被使用。

下面的代码中如果希望初始化方法对于子类一定可用,就将 init(num: Int) 声明为必须。

class ClassAAA {
let numA: Int
required init(num: Int) {
numA = num
}
required convenience init(bigNum: Bool) {
self.init(num: bigNum ? : )
}
} class ClassBBB: ClassAAA {
let numB: Int
required init(num: Int) {
numB = num +
super.init(num: num)
}
} let sencondObj = ClassBB(bigNum: true)
print(sencondObj.numA, sencondObj.numB)

输出:10000和10001

对于 convenience 的初始化方法也可以加上 required 以确保子类对其进行实现。

Swift的 convenience && designated init的更多相关文章

  1. Swift开发第十一篇——Designated、Convenience和Required

    本篇主要讲解 Swift 中 Designated.Convenience和 Required 的使用: 在 OC 中 init 方法是非常不安全的,没人能够保证 init 只被调用一次,也没有人保证 ...

  2. 【iOS】swift init构造器

    这几天在使用 Swift 重写原来的一个运动社交应用 SportJoin. 为什么要重写呢? 首先因为实在找不到设计师给我作图; 其次, 我也闲不下来, 想找一些项目做, 所以只好将原来的代码重写了. ...

  3. Swift中的init方法

    摘要:Swift有着超级严格的初始化方法,不仅强化了designated初始化方法的地位,所有不加修饰的init方法都需要在方法中确保非Optional的实例变量被赋值初始化,而在子类中,也强制调用s ...

  4. swift init继承问题

    当在子类的 designated init方法中不手动调用 父类的 designated init方法时,如果父类有不接受任何参数的init,那么系统会自动调用它,编译器不会报错.但是如果父类中没有不 ...

  5. IOS系列swift语言之课时五

    过了几天没来理博客了,这次我们要讲的有:类,属性,初始化init(),初始化器,构造器等 直接刷代码了....... //: Playground - noun: a place where peop ...

  6. 从0开始学Swift笔记整理(三)

    这是跟在上一篇博文后续内容: --Swift中相关的属性 存储属性 Swift中的属性分为存储属性和计算属性,存储属性就是Objective-C中的数据成员,计算属性不存储数据,但可以通过计算其他属性 ...

  7. Swift的初始化方法

    我们在深入初始化方法之前,不妨先再想想Swift中的初始化想要达到一种怎样的目的. 其实就是安全.在Objective-C中,init方法是非常不安全的:没有人能保证init只被调用一次,也没有人保证 ...

  8. Swift中类的初始化器与继承

    初始化是类,结构体和枚举类型实例化的准备阶段.这个阶段设置这个实例存储的属性的初始化数值和做一些使用实例之前的准备以及必须要做的其他一些设置工作. 通过定义构造器(initializers)实现这个实 ...

  9. Swift语法快速索引

    在WWDC的演示中就可以看出来Swift这个更接近于脚本的语言可以用更少的代码量完成和OC同样的功能.但是对于像我一样在战争中学习战争的同学们来说,天天抱着笨Swift Programming Lan ...

随机推荐

  1. 剑指offer——树的子结构 (JAVA代码)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 题目描述: 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构). 解题思路: 首先看牛客网给出的测试用例: ...

  2. 进制转换及API接口中的转换

    //十进制转二进制Console.WriteLine("十进制166的二进制表示: "+Convert.ToString(166, 2));//十进制转八进制Console.Wri ...

  3. XCode与Git的完美融合,不再依赖其它Git客户端

    Git源代码管理工具的出现,使得我们开发人员对于源码的管理更加方便快捷.至于Git的优点以及与其他源代码管理工具有何区别,不是本文的重点,如果想深入了解可以搜索一下这方面的文章.下面直接进入主题,如何 ...

  4. 渗透杂记-2013-07-13 windows/mssql/mssql_payload

    扫描一下 Starting Nmap 5.30BETA1 ( http://nmap.org ) at 2011-05-06 09:36 中国标准时间 NSE: Loaded 49 scripts f ...

  5. 在Windows系统下用命令把应用程序添加到系统服务

    在Windows系统下用命令把应用程序添加到系统服务,使用SC命令. 加入服务格式如下:sc create ServiceName binPath= 程序路径 start= auto(等号后面的空格是 ...

  6. JavaScript继承

    最佳的继承范式 寄生组合继承 我们来看一下它的实现方式: function Object(o){ var TempObject = function(){}; TempObject.prototype ...

  7. 读《编写可维护的JavaScript》第六章总结

    第六章 避免使用全局变量 JavaScript执行环境在很多方面都有其独特之处,全局变量就是其中之一.“全局变量”是一个神秘的对象,它表示了脚本的最外层上下文. 在浏览器中,windows对象往往重载 ...

  8. 编辑距离——Edit Distance

    编辑距离 在计算机科学中,编辑距离是一种量化两个字符串差异程度的方法,也就是计算从一个字符串转换成另外一个字符串所需要的最少操作步骤.不同的编辑距离中定义了不同操作的集合.比较常用的莱温斯坦距离(Le ...

  9. python走起之第八话

    1. Socket介绍 概念 A network socket is an endpoint of a connection across a computer network. Today, mos ...

  10. Nodejs学习总结 -Express入门(一)

    Express是基于Node.js平台开发的Web应用开发框架,下面我们入手学习. 官网 : http://www.expressjs.com.cn/ github:https://github.co ...