Failable Initializers

有的时候,可能是参数问题、需要的外部资源没有到位等原因,初始化可能失败。为了应对这种情况,我们可以定义一个或多个可失败的构造方法。 init?

A failable initiazlier creates an optional value of the type it initializes.

通过返回nil来表示初始化失败,看个例子:

struct Animal {
let species: String
init?(species: String) {
if species.isEmpty {
return nil
}
self.species = species
}
} let someCreature = Animal(species: "Giraffe")
//someCreature的类型是Animal?
if let giraffe = someCreature {
//
}

Failable Initializers for Enumerations

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
}
}
} let fahrenheitUnit = TemperatureUnit(symbol: "F")
if fahrenheitUnit != nil {
print("This is a defined temperature unit, so initialization succeeded.")
}
// Prints "This is a defined temperature unit, so initialization succeeded." let unknownUnit = TemperatureUnit(symbol: "X")
if unknownUnit == nil {
print("This is not a defined temperature unit, so initialization failed.")
}

Failable Initializers for Enumerations with Raw Values

Enumerations with raw values automatically receive a failable initializer, init?(rawValue):), that takes a parameter called rawValue of the appropriate raw-value type and selects a matching enumeration case if one if found, ro triggers an initialization failure if no matching value exists.

把上面的例子改写一下:

enum TemperatureUnit: Character {
case kelvin = "K", celsius = "C", fahrenheit = "F"
} let fahrenheitUnit = TemperatureUnit(rawValue: "F")
if fahrenheitUnit != nil {
print("This is a defined temperature unit, so initialization succeeded.")
}
// Prints "This is a defined temperature unit, so initialization succeeded." let unknownUnit = TemperatureUnit(rawValue: "X")
if unknownUnit == nil {
print("This is not a defined temperature unit, so initialization failed.")
}

Propagation of Initialization Failure

一个类、结构体、枚举的可失败的构造方法可以delegate across同一个类型中另一个可失败的构造方法。子类的一个可失败的构造方法可以delegate up父类的可失败的构造方法。

一个可失败的构造方法也可以delegate to不可失败的构造方法。

看个例子:

class Product {
let name: String
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
} class CartItem: Product {
let quantity: Int
init?(name: String, quantity: Int) {
if quantity < 1 { return nil }
self.quantity = quantity
super.init(name: name)
}
}

Overriding a Failable Initializer

父类的可失败的构造函数可以被重写为可失败的或者不可失败的。看个例子:

class Document {
var name: String?
// this initializer creates a document with a nil name value
init() {}
// this initializer creates a document with a nonempty name value
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
} class AutomaticallyNamedDocument: Document {
override init() {
super.init()
self.name = "[Untitled]"
}
override init(name: String) {
super.init()
if name.isEmpty {
self.name = "[Untitled]"
} else {
self.name = name
}
}
}

The init! Failable Initializer

init! implicitly unwrapped optional instance

Required Initiazliers

在构造方法的定义前边加上required修饰符来表示这个类的每一个子类都必须实现这个构造方法:

class SomeClass {
required init() { }
}

当重写一个required指定构造器时,不用在前边加override修饰。

注意:如果你可以使用一个继承的构造方法来满足的话,那么你可以不提供一个显式的required构造方法。

比如说我们定义一个子类:

class SomeSubClass: SomeClass {
required init() {
//
}
}

这样写,没有问题。我们也可以这样写:

class SomeSubClass: SomeClass {

}

这样写也没有问题,因为init()方法被自动继承了。我们接着看:

class SomeSubClass: SomeClass {
init(name: String) {
//
}
}

这样因为我们自定义了一个指定构造方法,SomeSubClass不会自动继承父类的指定构造方法(init()),所以编译器会提示我们一个错误。

Setting a Default Property

主要用途是为存储属性进行一些处理,可以使用全局函数或者闭包。看起来大概是这个样子:

class SomeClass {
let someProperty: SomeType = {
// create a default value for someProperty inside this closure
// someValue must be of the same type as SomeType
return someValue
}()
}

Swift: Initialization-2的更多相关文章

  1. iOS: 聊聊 Designated Initializer(指定初始化函数)

    iOS: 聊聊 Designated Initializer(指定初始化函数) 一.iOS的对象创建和初始化 iOS 中对象创建是分两步完成: 分配内存 初始化对象的成员变量 我们最熟悉的创建NSOb ...

  2. Swift 提示:Initialization of variable was never used consider replacing with assignment to _ or removing it

    Swift 提示:Initialization of variable was never used consider replacing with assignment to _ or removi ...

  3. Swift - 初始化Initialization

    Ps:苹果官方文档-Initialization 自定义控件初始化中常见的几种错误(指定构造器和便利构造器)截图:   意思是:1.没有添加重写符override(重写父类方法)2.没有重写initW ...

  4. Swift中懒加载(lazy initialization)的实现

    Swift中是存在和OC一样的懒加载机制的,但是这方面国内的资料比较少,今天把搜索引擎换成了Bing后发现用Bing查英文\最新资料要比百度强上不少. 我们在OC中一般是这样实现懒加载初始化的: 1: ...

  5. Lazy Initialization with Swift

    Lazy initialization (also sometimes called lazy instantiation, or lazy loading) is a technique for d ...

  6. Swift - 懒加载(lazy initialization)

    Swift中是存在和OC一样的懒加载机制的,在程序设计中,我们经常会使用 懒加载 ,顾名思义,就是用到的时候再开辟空间 懒加载 格式: lazy var 变量: 类型 = { 创建变量代码 }() 懒 ...

  7. Swift 的类、结构体、枚举等的构造过程Initialization(下)

    类的继承和构造过程 类里面的全部存储型属性--包含全部继承自父类的属性--都必须在构造过程中设置初始值. Swift 提供了两种类型的类构造器来确保全部类实例中存储型属性都能获得初始值,它们各自是指定 ...

  8. Swift学习笔记十四:构造(Initialization)

         类和结构体在实例创建时,必须为全部存储型属性设置合适的初始值. 存储型属性的值不能处于一个未知的状态.     你能够在构造器中为存储型属性赋初值,也能够在定义属性时为其设置默认值.下面章节 ...

  9. swift语言点评十六-Initialization && Deinitialization

    initial value:必须初始化.不影响观察者 Classes and structures must set all of their stored properties to an appr ...

  10. Swift 2 语言精要 - Initialization and Deinitialization

    init相当于构造函数 deinit相当于析构函数 class InitAndDeinitExample { // Designated (i.e., main) initializer init ( ...

随机推荐

  1. http拦截器interceptors

    在服务里配置$httpProvider.interceptors的相关参数 包含 request请求拦截 response响应拦截 requestError请求错误抛出 responseError响应 ...

  2. ecshop数据表

    ecs_account_log:账户变动日志(注册用户充值.支付等记录信息) ecs_ad:广告表 ecs_admin_action:管理员权限表(定义了128项功能操作) ecs_admin_log ...

  3. 项目知识点.Part2

    1. 取消collectionView头视图重叠情况:以下两种情况效果一样 但是有一点点bug 每次remove之后 需要把视图刷到上面才会显示(后续会改进方法) for (UIView *view ...

  4. 删除svn文件

    删除svn文件 sudo find . -name ".DS_Store" -exec rm -r {} \; sudo find . -name ".git" ...

  5. lsmod

    http://blog.csdn.net/yuan892173701/article/details/8960607 抽空写下

  6. Java JPA 查询实体部分字段

    前言 相信大家在用Java JPA作为ORM的时候都会有这种困惑,就是某个表T我仅仅希望取到其中的A.B.C三个字段,可是jpa是通过Entity Class映射的方式组合查询结果的. 那么如何通过使 ...

  7. [BZOJ 3747] [POI 2015] Kinoman【线段树】

    Problem Link : BZOJ 3747 题解:ZYF-ZYF 神犇的题解 解题的大致思路是,当区间的右端点向右移动一格时,只有两个区间的左端点对应的答案发生了变化. 从 f[i] + 1 到 ...

  8. ZABBIX作集中式NGINX性能监控的注意要点

    今天测试好了.但有几个要点要注意. 一是出了问题看日志. 二是主动测试脚本. 三是注意LLD自动发现的ZABBIX类型(TRAPPER,捕捉器类型) 四是有主机上有问题时可以看到(UNSUPPORT) ...

  9. 两个在线编写C++代码的网站

    第一个支持的编程语言很多,首推 http://ideone.com/ 第二个简单了点,不过可以通过email分享给朋友 http://codepad.org/ 试一试,可以用这两个网站提高自己编写代码 ...

  10. Linux下高并发网络编程

      Linux下高并发网络编程 1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时, 最高的并发数量都要受到系统对用户单一进程同时可打 ...