Swift的 convenience && designated init
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的更多相关文章
- Swift开发第十一篇——Designated、Convenience和Required
本篇主要讲解 Swift 中 Designated.Convenience和 Required 的使用: 在 OC 中 init 方法是非常不安全的,没人能够保证 init 只被调用一次,也没有人保证 ...
- 【iOS】swift init构造器
这几天在使用 Swift 重写原来的一个运动社交应用 SportJoin. 为什么要重写呢? 首先因为实在找不到设计师给我作图; 其次, 我也闲不下来, 想找一些项目做, 所以只好将原来的代码重写了. ...
- Swift中的init方法
摘要:Swift有着超级严格的初始化方法,不仅强化了designated初始化方法的地位,所有不加修饰的init方法都需要在方法中确保非Optional的实例变量被赋值初始化,而在子类中,也强制调用s ...
- swift init继承问题
当在子类的 designated init方法中不手动调用 父类的 designated init方法时,如果父类有不接受任何参数的init,那么系统会自动调用它,编译器不会报错.但是如果父类中没有不 ...
- IOS系列swift语言之课时五
过了几天没来理博客了,这次我们要讲的有:类,属性,初始化init(),初始化器,构造器等 直接刷代码了....... //: Playground - noun: a place where peop ...
- 从0开始学Swift笔记整理(三)
这是跟在上一篇博文后续内容: --Swift中相关的属性 存储属性 Swift中的属性分为存储属性和计算属性,存储属性就是Objective-C中的数据成员,计算属性不存储数据,但可以通过计算其他属性 ...
- Swift的初始化方法
我们在深入初始化方法之前,不妨先再想想Swift中的初始化想要达到一种怎样的目的. 其实就是安全.在Objective-C中,init方法是非常不安全的:没有人能保证init只被调用一次,也没有人保证 ...
- Swift中类的初始化器与继承
初始化是类,结构体和枚举类型实例化的准备阶段.这个阶段设置这个实例存储的属性的初始化数值和做一些使用实例之前的准备以及必须要做的其他一些设置工作. 通过定义构造器(initializers)实现这个实 ...
- Swift语法快速索引
在WWDC的演示中就可以看出来Swift这个更接近于脚本的语言可以用更少的代码量完成和OC同样的功能.但是对于像我一样在战争中学习战争的同学们来说,天天抱着笨Swift Programming Lan ...
随机推荐
- ODBC简介
加载驱动 1 oracle Class.forName("oracle.JDBC.driver.OracleDriver") 2 DB2 Class.forName("c ...
- Logstash学习-配置语法
区段(section) Logstash 用{}来定义区域.区域内可以包括插件区域定义,你可以在一个区域定义多个插件,插件区域内则可以定义键值对设置. 数据类型 Logstash支持少量的数据值类型: ...
- asp之缓存 cachestate
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- ipad pro 文章
这篇文章是通过iPad Pro发送的.体验一下键盘输入,以及safari下的输入.这个键盘的输入手感好一般,按键行程较短.
- [转]vb socket通信(TCP/UDP)一对一、多对一
VB Socket编程(Winsock控件创建TCP/IP客户机/服务器程序) Winsock控件建立在TCP.UDP协议的基础上,完成与远程计算机的通信.即使对TCP/IP不太熟悉的用户,使用 ...
- ImageLoader图片加载
http://blog.csdn.net/liu1164316159/article/details/38728259 转载请注明http://write.blog.csdn.net/po ...
- 准备阶段-maven项目构建
依据我现阶段对maven的了解,具使用POM管理项目和强大的repository资源管理库支持. 在项目建立初期,对网站的可拓展.高并发.易于管理做了评估.最终使用Maven 管理该项目 . 如下是m ...
- OpenModelica仿真
复杂产品通常涉及机械.控制.电子.液压.气动和软件等多学科领域,其设计过程需要进行仿真,以满足对成本.质量.性能等的要求.目前各个学科和领域都已经有了比较成熟的仿真软件,但大部分仿真软件仅适用于本学科 ...
- Obtaining Query Count Without executing a Query in Oracle D2k
Obtaining Query Count Without executing a Query in Oracle D2k Obtaining a count of records that will ...
- WinForm开发框架【细化权限至操作按钮】
有不少园友经常问我程序有没有更新,真的很抱歉,最近因为工作原因一直很忙,导致程序有很长时间都没有更新了,首先在这里感谢关心俺的朋友们. 这几天好好看了一下原来的程序,还有很多地方需要改进,比如操作数据 ...