Swift开发第二篇——extension及fatalError
本篇分两部分:
一、extension在 Swift 中的使用
二、Swift 中的 fatalError
一、extension在 Swift 中的使用
在 swift 中我们可以通过 extension 来输出做格式化等操作
通常情况下,当我们在开发过程中需要打印某些对象中的信息时,我们会编写如下代码:
struct Meeting {
var date: NSDate
var place: String
var attendeeName: String
}
let meeting = Meeting(date: NSDate(timeIntervalSinceNow: ),
place: "会议室B",
attendeeName: "小明")
print(meeting)
print("与 \(meeting.date) 在 \(meeting.place) 与 \(meeting.attendeeName) 进行会议")
输出结果: 
这种开发方式在 Swift 中可以算得上是非常传统的代码了,如果我们需要输出其他对象的一些信息时,会不断手动实现上面的代码,如果过于频繁会大大降低开发效率,所以,这里我们可以利用 extension 特性来进行优化。
extension Meeting: CustomStringConvertible {
var description: String {
return "与 \(meeting.date) 在 \(meeting.place) 与 \(meeting.attendeeName) 进行会议"
}
}
print(meeting)
输出结果: 
二、Swift 中的 fatalError
let array: NSArray = [,,]
上面的数组长度为3,如果我们在开发过程中由于某些原因,在使用上面的数组时写成了 array[100] 就会报数组越界错误,程序崩溃。
在 OC 中数组越界输出的错误信息为:*** Terminating app due to uncaught exception 'NSRangeException',reason: '*** -[__NSArrayI objectAtIndex:]:index 100 beyond bounds [0 .. 2]'
在 Swift 中为 fatal error: Array index out of range
在调试时我们可以用断言来排除类似这样的问题,但是断言只会在 Debug 环境中有效,而在 Release 编译中所以变得断言都将被禁用。所以我们会考虑以产生致命错误(fatalError)的方式来种植程序。
enum MyEnum {
case Value1,Value2,Value3
}
func check(someValue: MyEnum) -> String {
switch someValue {
case .Value1:
return "OK"
case .Value2:
return "Maybe OK"
default:
// 这个分支没有返回 String,也能编译通过
fatalError("Should not show!")
// return "Should not show!"
}
}
let a = check(.Value3)
这时如果我们传入的参数不属于指定范围,这里就会报错
当我们在开发过程中,遇到不想让别人调用而又不得不将其暴漏出来的方法时,一个最常见并且合理的需求就是”抽象类型或者抽象函数“。在很多语言中都有这样的特性:父类定义了某个方法,但是自己并不给出具体实现,而是要求继承他的子类去实现这个方法,而在 OC 和 Swift 中都没有直接的这样的抽象函数语法支持。在面对这种情况时,为了确保子类实现这些方法,而父类中的方法不被错误的调用,我们就可以利用 fatalError 来在父类中强制抛出错误,以保证使用这些代码的开发者留意到他们必须在自己的子类中实现相关方法。
class MyClass {
func methodMustBeImplementedInSubclass() {
fatalError("这个方法必须在子类中被重写") }
}
class YourClass: MyClass {
override func methodMustBeImplementedInSubclass() {
print("YourClass 实现了该方法") }
}
class TheirClass: MyClass {
func someOtherMethod() {
}
// override func methodMustBeImplementedInSubclass() {
// print("TheirClass 实现了该方法")
// }
}
YourClass().methodMustBeImplementedInSubclass()
TheirClass().methodMustBeImplementedInSubclass()
这个方法必须在子类中被重写,否则会编译报错
不仅仅是对于类似抽象函数的使用中可以选择 fatalError,对于其他一切我们不希望别人随意调用,但是又不得不去实现的方法,我们都应该使用 fatalError 来避免任何可能的误会。比如父类标明了某个 init 方法是 required 的,但是你的子类永远不会使用这个方法来初始化时,就可以采用类似的方法,被广泛使用(以及被广泛讨厌的)init(coder: NSCoder)就是一个例子。在子类中我们往往会写:
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
来避免编译错误。
Swift开发第二篇——extension及fatalError的更多相关文章
- swift开发多线程篇 - 多线程基础
swift开发多线程篇 - 多线程基础 iOS 的三种多线程技术 (1)NSThread 使用NSThread对象建立一个线程非常方便 但是!要使用NSThread管理多个线程非常困难,不推荐使用 ...
- iOS开发——高级技术精选&底层开发之越狱开发第二篇
底层开发之越狱开发第二篇 今天项目中要用到检查iPhone是否越狱的方法. Umeng统计的Mobclick.h里面已经包含了越狱检测的代码,可以直接使用 /*方法名: * isJailbroken ...
- android 串口开发第二篇:利用jni实现android和串口通信
一:串口通信简介 由于串口开发涉及到jni,所以开发环境需要支持ndk开发,如果未配置ndk配置的朋友,或者对jni不熟悉的朋友,请查看上一篇文章,android 串口开发第一篇:搭建ndk开发环境以 ...
- swift开发网络篇—NSURLConnection基本使用
iOS开发网络篇—NSURLConnection基本使用 一.NSURLConnection的常用类 (1)NSURL:请求地址 (2)NSURLRequest:封装一个请求,保存发给服务器的全部数据 ...
- 微信支付之JSAPI开发-第二篇:业务流程详解与方案设计
微信支付流程 流程: 上图的网址为:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_4 如上图所示,微信网页支付的具体流程大致分为 ...
- Swift开发第一篇——异常处理及断言
本篇分两部分: 1.错误和异常处理 2.Swift 中的断言 1.错误和异常处理 在 OC 开发中,我们通常会将 error 置为 nil NSError *error; BOOL success = ...
- Swift开发第九篇——Any和AnyObject&typealias和泛型接口
本篇分为两部分: 一.Swift中的Any和AnyObject 二.Swift中的typealias和泛型接口 一.Swift中的Any和AnyObject 在 Swift 中,AnyObject 可 ...
- SAP web 开发 (第二篇 bsp 开发 mvc模式 Part2 )
单击第一个图标,第一个图标突出显示,单击第二个图标,第一个变灰,第二个突出显示,反之一样.单击history读取历史记录. Controller ZCL_SUS_C_ORDER_CHANGE 1. ...
- PowerBI开发 第二篇:数据建模
在分析数据时,不可能总是对单个数据表进行分析,有时需要把多个数据表导入到PowerBI中,通过多个表中的数据及其关系来执行一些复杂的数据分析任务,因此,为准确计算分析的结果,需要在数据建模中,创建数据 ...
随机推荐
- oracle 表被锁了解决方案
使用下面的语句来查询被锁定的表: SELECT /*+ rule */ lpad(' ',decode(l.xidusn ,0,3,0))||l.oracle_username User_name, ...
- ADO.NET基础巩固-----连接类和非连接类
最近的一段时间自己的状态还是不错的,早上,跑步,上自习看书,下午宿舍里面编程实战,晚上要么练习代码,要么去打球(在不打就没机会了),生活还是挺丰富的. 关于C#的基础回顾就先到前面哪里,这 ...
- 基于cookie实现zTree树刷新后,展开状态不变
1.除了引用jQuery和zTree的JS外,引用cookie的JS: <script type="text/javascript" src="~/Scripts/ ...
- 解决android sdk 无法更新
今天更新sdk,遇到了更新下载失败问题: Fetching https://dl-ssl.google.com/android/repository/addons_list-2.xmlFetched ...
- EF生成 类型“System.Data.Entity.DbContext”在未被引用的程序集中定义
错误描述: 1 类型“System.Data.Entity.DbContext”在未被引用的程序集中定义.必须添加对程序集“EntityFramework, Version=5.0.0.0, Cult ...
- Win10 IoT C#开发 3 - GPIO Pin 控制发光二极管
Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一篇文 ...
- Android使用SQLite数据库(2)
打开SQLite数据库,首先要建立一个DatabaseHelper类的实例,然后,再获得数据库: DatabaseHelper mDBH; SQLiteDatabase db; mDBH = new ...
- JAVA获取CLASSPATH路径
ClassLoader 提供了两个方法用于从装载的类路径中取得资源: public URL getResource (String name); public InputStream getResou ...
- EL表达式之sessionScope
EL 全名为Expression Language EL 语法很简单,它最大的特点就是使用上很方便.接下来介绍EL主要的语法结构: ${sessionScope.user.sex} 所有EL都是以 $ ...
- win系统盘下面安装RedHat Linux6.2ES
安装中的流程和问题 1.安装准备 硬盘分区 下载rhel-server-6.2-i386-dvd.iso 接下来就是一些安装过程 2.安装教程有很多,可以结合参考: http://www.dedecm ...