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中,通过多个表中的数据及其关系来执行一些复杂的数据分析任务,因此,为准确计算分析的结果,需要在数据建模中,创建数据 ...
随机推荐
- ASP.NET MVC系列:添加视图
虽然在上一篇文章中我们知道通过控制器可以在浏览器输出HTML页面,但是这不是控制器主要干的事,因为页面上我为还要做很多好看的特效,页面展示的事情当然交给视图来做了:下面我们就来看看如何添加一个视图 添 ...
- QQ--模拟发表带图说说
发表说说之前,必须登录. 模拟QQ登录 >> http://www.cnblogs.com/deeround/p/4386629.html 发表带图说说,自然少不了上传图片,我这使用的PC ...
- JsonConvert 使用注意事项之 Serializable
1.使用NuGet安装Newtonsoft.Json. 2.创建需要序列化的类. public class Person { public string Name{get;set;} public i ...
- android多分辨率多密度下界面适配方案
前言 Android 设计之初就考虑到了UI在多平台的适配,它本身提供了一套完善的适配机制,随着版本的发展适配也越来越精确,UI适配主要受平台两个因素的影响:屏幕尺寸 (屏幕的像素宽度及像素高度)和屏 ...
- 不可或缺 Windows Native (12) - C++: 引用类型
[源码下载] 不可或缺 Windows Native (12) - C++: 引用类型 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 引用类型 示例CppReferen ...
- [控件] 加强版 TOneSelection (改良自 Berlin 10.1 TSelection)
本控件修改自 Delphi Berlin 10.1 的 TSelection (FMX.Controls.pas) 修改重点: 移动点显示在上方 增加(左中,上中,右中,下中)控制点,含原来的总共有 ...
- 用 Inkspace 做 SVG 给 TPath
FireMonkey 里的 TPathData 支持 SVG 的基本绘图指令,因此可以运用 Inkspace 软件,提取 SVG 的绘图内容,请见图片说明:
- django pdb
import pdb; pdb.set_trace() http://charlee.li/debug-djangp-with-pdb.html https://github.com/tomchr ...
- EasyUI-扩大在DataGrid显示次网格的行
一.下载并引用:datagrid-detailview.js脚本文件 二.添加UrlInfo控制器,添加Index页面代码如下: @{ Layout = null; } <!DOCTYPE ht ...
- 泛函编程(33)-泛函IO:Free Functor - Coyoneda
在前几期讨论中我们终于推导出了Free Monad.这是一个Monad工厂,它可以把任何F[A]变成Monad.可惜的是它对F[A]是有所要求的:F必须是个Functor.Free Monad由此被称 ...