Swift(3.0)之入门


前言

Swift,苹果于2014年WWDC(苹果开发者大会)发布的新开发语言,可与Objective-C 共同运行于Mac OSiOS平台,用于搭建基于苹果平台的应用程序。

在2016年的WWDC上,Swift 3.0是随着iOS 10和Xcode 8一起发布的。使用Xcode 8适配Swift 3.0的过程中,你会意识到Swift 3.0有很大的改动,也许你认为从Swift 1.2到2.0已经是很大的改动,我觉得这真的不算什么,因为你还没有见到swift 3.0的全貌,它的改动更多更大。本文是基于Swift 3.0带你初步认识Swift的基础的,仅学习和参考使用。

进入主题

1. 常量和变量

Swift中定义常量和变量分别使用 let / var    let:用来定义一个常量  var:用来定义一个变量。常量名和变量名是可以用中文的。

常量是不能修改的,修改是会报错的, 变量却是相反,是可以修改的。在Swift中定义一个常量和变量不需要写明数据类型,因为编译器会根据后面的数据自动推算出对应的类型,如下图我定义分别一个常量和一个变量。通过 option+左键  可以查看对应的类型。  下面的代码截图中,只需要将第二行代码删除即可消除错误。

常量名和变量名使用中文如下截图:

注意点:  Swift开发中每一条语句后面不需要写分号,但是写上去也不会报错的,如果同一行有多条语句,那么每一条语句后面必须加上分号,不然编译器不能区分从而报错!

2. 数据类型转换

Swift中不存在隐式类型转换,所有的类型转换必须是显示的,因为Swift是强语言,OC是弱语言,写法如下截图。

3. Bool和Switch

Swift中的 if 使用方式基本和OC一致,但是在Swift中的 if 可以省略 () ,然而在Swift中哪怕 if 后面只有一条语句,也是不能省略 {} 的,但是在OC中是可以的。还有在OC和C或者Java中,一直有个真理:非零即真,但是在Swift中,条件只能放bool类型,所以只能是 true 或者 false。

 Swift中的Switch 后面的()可以省略掉

在OC中的Switch如果没有break会穿透,但是在Swift中是不会的

OC中如果要在case中间定义变量,必须加上 {} 确定作用域,而在Swift中是不用的

在OC中default的位置是可以随便写的,只有所有的条件不满足才会执行default,但是在Swift中的default只能放在最后面

 OC中的default可以省略,但是在Swift中大部分是不能省略的

4. 三目运算符(三元运算符)和Optional(可选)

三目运算符中的?前后一定要用空格空开,不然会报错

Optional 是一种可选类型,代表的是可有可无,就像OC中的代理方法可以设置为Optional一样

以后凡是看到一个方法和数据类型后面有?的,就是代表的是一个可选类型(Optional),创建出来的对象就有可能为nil

使用可选类型需要注意,如果直接打印可选类型,那么打印出来的值是会被Optional包裹

如果我们使用过程中遇到可选类型,可以通过使用!强制解析,告诉编译器可选类型一定有值(直接在对象后面加!),如果解析后的对象不为空,那么打印出来的就不会包含Optional

但是如果我们强制解析,而可选类型没有值的话,那么程序就会奔溃

5. for循环和While循环

直接上截图 for循环

直接上截图while循环,注意点: do while中的do没有了,因为do被用作捕获异常了,用 repeat 代替

6. 元组

元组(tuples)把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。元组很像C语言中的结构体,但是元组其实就是值传递,而不是引用。元组使用的最佳场景就是当一个函数返回多个不同的类型时,可以返回元组实现。

7. 数组和字典

Swift中的数组和OC中的区别就是:去掉前面的@符号 ,遍历数组就通过元组去遍历


Swift中的字典创建和创建数组一样,都是用[],不过字典是通过 : 来区分一个key对应一个值的,和数组一样,也是通过分号(,)区分下一个元素

[String:NSObject] 类型是IOS开发中最常见的一种格式

8. 字符串

在Swift中使用 "" 定义字符串,在OC中字符串的类型是NSString,而在Swift中却是String

在OC中字符串是一个对象,继承于NSObject,而在Swift中字符串是一个结构体,所以其性能要比OC中的强

9. 函数(方法)


Swift中函数的定义为: func +函数名字(参数名:参数类型,参数名:参数类型) -> 返回类型{}

下面截图分别定义四种不同的函数

定义完对应的函数后,我们要调用,调用方式为:  self.函数名 或者 直接函数名

我们可以通过函数名以及对应类型的参数值来调用函数,函数的参数传递的顺序必须与参数列表相同。


上面的都是对应的实例方法,下面就说一下最后的类方法(通过类名去调用)。类方法就是在实例方法的前面加关键字class(在func前面加class),类型方法和实例方法一样用点号(.)语法调用。

10. 闭包(相当于OC中的Block)

闭包和OC中的Block是很相似的,OC中的Block是匿名的函数

在Swift中的闭包也是用来定义一个函数回调用的,所以也是一个函数哈

闭包的基本格式: 闭包名字:(形参列表)->返回类型, (就是函数的写法)

func easyName(finish:(_ intValue:Int)->String,_ string:String){}  // 这句代码的意思是定义了一个名字为easyName的函数,函数里面有两个参数,其中一个是闭包类型的finish , 其中一个就是String类型的string,这里面的 (_ intValue:Int)->String 就是一个闭包,闭包传入一个Int类型和返回一个String类型

闭包的展开基本格式: { (形参列表) -> 返回值 in 需要执行的代码 }  // in 的含义是用于区分形参返回值和执行代码

// 例子 { (a:Int,b:Int)->Int in return a+b  }    // 这句代码的意思是: 闭包分别传过来了两个Int类型的a 和 b 并且要返回一个Int类型, in 后面执行的代码就是闭包的返回值(a+b)

1.  函数只有一个参数,并且这个参数是闭包,写法如下:

2. 函数中的多个参数和一个闭包,写法如下:

3. 函数中的多个参数和多个闭包,写法如下:

4. 给闭包定义一个别名

typealias 是Swift中用来为已经存在的类型重新定义名字的关键字(类似于OC语法中的 typedef),重新命名的新名字用来替代之前的类型,并且能够使代码变得更加清晰简单容易理解。typealias 的用法很简单,直接用 = 赋值就可以了

typealias <type name>= <type expression>

下面我这边直接使用闭包别名  AllActionName2 作为函数的参数使用,如下截图


调用函数 easyUseClosure () 如下截图结果

5. 闭包的循环引用问题

我这里先定义一个闭包的属性,通过函数去强引用,然后在回调里面去调用本控制器中的view中的背景颜色,具体操作和解决方法如下:



上面函数前面的private(私有) 关键字  是用来说明这个函数只能在本类中使用,是私有的函数,不能被外部使用。

@escaping 关键字是 所有的闭包都默认为非逃逸闭包,不再需要@noescape;如果是逃逸闭包,就用@escaping表示。  (如果这个闭包是在这个函数结束前内被调用,就是非逃逸的即noescape。如果这个闭包是在函数执行完后才被调用,调用的地方超过了这函数的范围,所以叫逃逸闭包)。
 


11. 枚举

枚举简单的说也是一种数据类型,只不过是这种数据类型只包含自定义的特定数据,它是一组有共同特性的数据的集合

Swift 中使用 enum 关键词来创建枚举并且把它们的整个定义放在一对大括号内:

enum  enumname{

// 枚举定义放在这里

}

定义如下:


使用如下截图:

12. 结构体

Swift 结构体是构建代码所用的一种通用且灵活的构造体,我们可以为结构体定义属性(常量、变量)和添加方法,从而扩展结构体的功能。

与 C 和 Objective C 不同的是:1. 结构体不需要包含实现文件和接口。 2. 结构体允许我们创建一个单一文件,且系统会自动生成面向其它代码的外部接口。

结构体总是通过被复制的方式在代码中传递,因此它的值是不可修改的。

我们通过关键字 struct 来定义结构体, 定义如下:


使用和调用如下:


从实例中我们可以很好的理解到: 结构体实例是通过值传递的而不是通过引用传递。

按照通用的准则,当符合一条或多条以下条件时,请考虑构建结构体:

1. 结构体的主要目的是用来封装少量相关简单数据值

2. 有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用

3. 任何在结构体中储存的值类型属性,也将会被拷贝,而不是被引用

4. 结构体不需要去继承另一个已存在类型的属性或者行为

举例来说,以下情境中适合使用结构体:

1. 几何形状的大小,封装一个width属性和height属性,两者均为Double类型

2. 一定范围内的路径,封装一个start属性和length属性,两者均为Int类型

3. 三维坐标系内一点,封装x,y和z属性,三者均为Double类型

13. 类

类是构建代码所用的一种通用且灵活的构造体,我们可以为类定义属性(常量、变量)和函数(方法)。

通过关键字 class + 类名 +继承的类(可以不用继承)+{}

与其他编程语言所不同的是,Swift 并不要求你为自定义类去创建独立的接口和实现文件。你所要做的是在一个单一文件中定义一个类,系统会自动生成面向其它代码的外部接口。

我这里新建一个TestClass的类


使用类:

类名.init()  然后调用其里面的属性 方法


14. 属性和Setting以及Getting方法

在Swift中,如果在某个类中定义一个属性,那么这个属性是要初始化的,否则就是报错

如果占用时不想初始化,那么可以在后面添加一个?号,可选类型

下面直接通过调用函数,在函数里面赋值和打印查看效果,截图如下:


Swift中的 set 和 get 方法直接在属性的后面添加{ get{} set{} } 具体如下:

调用和打印如下:

在OC中通过关键字 readOnly 修饰 重写 getting方法就是只读属性, 在Swift中 只重写 getting方法,不重写 setting方法就是 只读属性,而且这个属性称之为计算型属性,这个计算型属性是不占内存空间的


属性中还有一个方法可以重写, didSet{}   这个当我设置完属性的值之后会被调用的,具体如下



15. 下标脚本

下标脚本可以定义在类(Class)、结构体(structure)和枚举(enumeration)这些目标中,可以认为是访问对象、集合或序列的快捷方式,不需要再调用实例的特定的赋值和访问方法。

举例来说,用下标脚本访问一个数组(Array)实例中的元素可以这样写 someArray[index] ,访问字典(Dictionary)实例中的元素可以这样写 someDictionary[key]。

对于同一个目标可以定义多个下标脚本,通过索引值类型的不同来进行重载,而且索引值的个数可以是多个。

与定义实例方法类似,定义下标脚本使用subscript关键字,显式声明入参(一个或多个)和返回类型。

与实例方法不同的是下标脚本可以设定为读写或只读。这种方式又有点像计算型属性的getter和setter

这边我在结构体体重定义一个下标脚本:

调用和返回的值是:

在类中使用一个下标脚本:

调用结果如下:

16. 继承

一个类获取了另外一个类的方法和属性,这就是继承。

当一个类继承其它类时,继承类叫子类,被继承类叫超类(或父类)。

在 Swift 中,类可以调用和访问超类的方法,属性和下标脚本,并且可以重写它们。

没有继承其它类的类,称之为基类(Base Class)。

子类可以通过继承来的实例方法,类方法,实例属性,或下标脚本来实现自己的定制功能,我们把这种行为叫重写(overriding),我们可以使用 override 关键字来实现重写。

调用和对应的结果如下:



17. 类型转换

Swift 语言类型转换可以判断实例的类型。也可以用于检测实例类型是否属于其父类或者子类的实例

Swift 中类型转换使用 is 和 as 操作符实现。

is 来检查一个实例是否属于特定子类型。若实例属于那个子类型,类型检查操作符返回 true,否则返回 false。

向下转型,用类型转换操作符(as? 或 as!)。当你不确定向下转型可以成功时,用类型转换的条件形式(as?)。条件形式的类型转换总是返回一个可选值(optional value),并且若下转是不可能的,可选值将是 nil。只有你可以确定向下转型一定会成功时,才使用强制形式(as!)。当你试图向下转型为一个不正确的类型时,强制形式的类型转换会触发一个运行时错误。

类型转换也可以用来检查一个类是否实现了某个协议

Swift为不确定类型提供了两种特殊类型别名: AnyObject可以代表任何class类型的实例。Any可以表示任何类型,包括方法类型(function types)。

我这里新建一个继承于的SonClass的孙子类,SonClass是继承于 baseClass的

调用和使用如下截图:


18. 懒加载

懒加载的格式:定义变量前使用 lazy 关键字来修饰,后面通过赋值一个闭包

注意点 1.必须使用 var 2.闭包后面必须跟上()

如果闭包用于懒加载,那么in之前的代码都可以删掉,包括in在内


19. 构造方法

我这边测试新建一个继承NSObject的类,名字为: TestClass  在类中添加 name hobby和age三个属性,通过重写构造方法和自定义构造方法给三个属性分别赋值,具体操作如下:

类的函数调用和打印如下:

20. 命名空间

在Swift中,如果想使用一个类,是不需要导入(import)对应的头文件的,因为Swift中新增了一个叫做"命名空间"的概念,只要是在同一个命名的空间中,那么资源都是共享的,默认的情况下,项目名称就是命名空间,如下截图,我这边的命名空间就是:Test_Swift  。可以从截图中看出 ViewController是在其命名空间之中的。

. 将字符串转为类(动态获取命名空间)

具体代码如下:


方法的调用如下

21. 扩展(extension),相当于OC中的类别

给对应的类或者系统的类添加方法或者属性。

写法: 写在类的外面,用关键字 extension 修饰,后面跟随着要扩展的对应的类,然后在{}里面写要扩展的方法或者属性

以上面的获取动态空间为例,我给Bundle 扩充一个方法和一个属性,方法就是用来获取命名空间的,属性的话就简单的一个打印操作吧。具体实现如下截图:

代码的调用和打印如下:


22. 协议

协议规定了用来实现某一特定功能所必需的方法和属性。

任意能够满足协议要求的类型被称为遵循(conform)这个协议。

类,结构体或枚举类型都可以遵循协议,并提供具体实现来完成协议定义的方法和功能。

协议的语法格式如下:

protocol  协议名字 { // 协议内容 }

要使类遵循某个协议,需要在类型名称后加上协议名称,中间以冒号:分隔,作为类型定义的一部分。遵循多个协议时,各协议之间用逗号,分隔。

struct 结构体名字:FirstProtocol,AnotherProtocol{ // 结构体内容 }

如果类在遵循协议的同时拥有父类,应该将父类名放在协议名之前,以逗号分隔。

class 类名:父类名,FirstProtocol,AnotherProtocol{ // 类的内容 }

具体定义一个协议和遵守如下截图:


调用如下:


23. 泛型

Swift 的数组和字典类型都是泛型集

你可以创建一个Int数组,也可创建一个String数组,或者甚至于可以是任何其他 Swift 的类型数据数组

 

最后,原文Demo地址

可以通过下面的截图快速查看和学习


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 3,771评论 1 10
  • Swift 介绍 简介 Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X 和 iOS 应用程序 ...
    大L君阅读 3,168评论 3 25
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,019评论 4 62
  • 常量与变量使用let来声明常量,使用var来声明变量。声明的同时赋值的话,编译器会自动推断类型。值永远不会被隐式转...
    莫_名阅读 436评论 0 1
  • 小时候吧盼望着长大, 现在真正长大到了小时候的年龄,却发现了很多很多并不是那时候想象的那般美好… 我记得小时候我总...
    薇小汐阅读 215评论 0 0