2018-02-09 14:54:36 ZY_FlyWay 阅读数 1604

Swift 4.0访问权限关键字

    目前有 open  public  internal  fileprivate  private 这五个访问权限,都可以修饰属性和方法。下面通过例子来分析五个访问权限的使用。


不同点分析:

  • 是否可以被子类继承访问
  • 同文件不同类下是否可以访问
  • 不同文件是否可以被访问
  • 不同组件下是否可以被访问

1、private

被private修饰的属性和方法  ,只可以在该类下使用(extension可使用,因为是同类。)

例如:下面图片,即使在同文件下不同类也是不能调用的,继承的话子类也不能调用。



2、fileprivate

      fileprivate和private 想比较一下,区别一目了然,相同文件下是可以调用的,其他和private一样。

 

3、internal 

 

      默认权限,如果项目没有进行组件化开发,整个APP项目内都是可以访问的。

 

4、public

 可以被任何人访问,但是在其他module中不可以被继承和重写,在当前module内可以


5、open  


  最高权限,可以被任何module和文件访问和继承重写


2017-09-02 09:52:38 tinghe17 阅读数 2730

基于Swift 的AppleWatch 开发教程

(一)内容简介

本书使用swift的新版本(2.0或以上),针对Apple Watch的基本编程和watch OS 3开放的众多新接口进行撰写,主要包括表盘、音频视频和多种传感器等,功能新颖,紧随穿戴设备流行趋势,内容全面,代码齐全,讲解清楚,可以让读者深入浅出地掌握Apple Watch开发。


(二)目录

1 概述 1

1.1  watchOS项目结构 1

1.2  建立watchOS App实例 2

1.3  watchOS 3框架支持 4

1.4  【案例1watchOS 3项目结构 5

2  Swift 3编程基础 8

2.1  基本语法 8

2.1.1  变量和常量 8

2.1.2  guard letif let 10

2.1.3  字符串String 11

2.1.4  数组 13

2.1.5  枚举 14

2.1.6  for循环 15

2.1.7  switch/case多条件判断 15

2.1.8  任意类Any 16

2.2  函数 16

2.2.1  声明和调用 16

2.2.2  回调函数 17

2.2.3  异常抛出和捕捉 18

2.3  常用数据结构和类 18

2.3.1  字典Dctionary 18

2.3.2  日期Date 21

2.3.3  计时器Timer 23

2.3.4  文件存储 24

2.4  Objective-C混合编程 25

3  watchOS基础开发 26

3.1  页面控件 26

3.1.1  页面生命周期 26

3.1.2  页面关系 26

3.2  常用控件 27

3.2.1  表盘布局和Group 27

3.2.3  图片 28

3.2.4  按钮 28

3.2.5  开关 28

3.2.6  滑动条 29

3.2.7  选择器 29

3.2.8  表格 30

3.3  应用图标 32

3.4  【案例2】宠物乐园 33

4  WatchOS高级进阶 40

4.1  Force Touch菜单 40

4.2  振动引擎 40

4.3  表盘功能栏 41

4.3.1  功能栏简介 41

4.3.2  功能栏刷新 42

4.3.3  Watch表盘图库示例 43

4.3.4  家族和模板 44

4.3.5  家族示意图 45

4.3.6  模板示意图 46

4.3.7  功能栏图片尺寸 50

4.4  提醒 51

4.5  后台刷新任务 52

4.6  URL后台下载 53

4.7  Dock截图 53

4.8  Apple Pay支付 54

4.9  通知 54

4.10  【案例3】十二生肖 55

4.11  【案例4】后台刷新任务和URL下载 64

5 多媒体和游戏引擎 69

5.1  多媒体 69

5.1.1  录音 69

5.1.2  无线播放音频 69

5.1.3  视频播放和喇叭外放 70

5.2  游戏引擎 70

5.2.1  2D游戏引擎控件 70

5.2.2  创建手表游戏项目 71

5.2.3  3D游戏引擎控件 71

5.2.4  手势识别 71

5.3  【案例5】录音和音频视频播放 72

5.4  【案例62D游戏 74

5.5  【案例73D游戏 80

6 运动传感器和GPS 92

6.1  运动传感器 92

6.2  传感器记录 94

6.3  运动姿态识别 94

6.4  GPS和定位 94

6.5  地图控件 95

6.6  【案例8】运动传感器 95

6.5  【案例9GPS定位 105

7 iPhone交互 109

7.1  WatchConnectivity框架 109

7.2  配置WCSession 109

7.3  连接状态 109

7.3.1  判断连接状态 109

7.3.2  连接状态回调 110

7.4  数据传输 110

7.4.1  覆盖式后台传输 110

7.4.2  队列式后台传输 110

7.4.3  文件传输 111

7.4.4  消息传输 111

7.4.5  消息数据传输 111

7.4.6  功能栏传输 112

7.5  【案例10】与iOS交互 112

8 健康 120

8.1  健康存储的数据 120

8.1.1  人体特征数据 120

8.1.2  样本数据 121

8.1.3  样本数据类型 121

8.1.4  数据单位 124

8.1.5  病历 124

8.2  监测数据 124

8.2.1  加载健康框架 124

8.2.2  申请权限 125

8.2.3  后台模式 125

8.2.4  监测体能训练 126

8.2.5  活动类型 129

8.2.6  存储到健康库 131

8.3  【案例11】健身监测和体能训练 132

三、内容介绍

本书包括8章。第1章概述,介绍watchOS项目的结构组成,并列举了已经提供部分和完全支持的框架。

2Swift编程基础,Swift更新到第3个版本已经基本稳定,该部分介绍了Swift的基本语法、函数调用、常用数据结构和类,为后续开发做好准备。

3watchOS基础,开始正式进入watchOS应用的开发,介绍了页面和常用控件。

4watchOS高级进阶,是第3watchOS基础开发的进一步深入,主要涉及按压交互和组件交互,具体内容包括Force Touch菜单、振动引擎、表盘功能栏、提醒、后台刷新任务、URL后台下载、Dock截图、Apple Pay、通知等多种高级功能。

5章多媒体和游戏引擎,多媒体包括录音、连接蓝牙耳机播放音频、视频播放和喇叭外放,游戏引擎包括2D引擎SpriteKit3D引擎SceneKit,这里还结合游戏讲解了手势交互。

6章运动传感器和GPSApple Watch已经明确支持加速计、陀螺仪两种主要运动传感器,同时也支持GPS定位。

7章与iPhone交互,Apple Watch不是iPhone的附属部件,而是运行独立操作系统的独立计算机,与iPhone之间进行平等的数据交换,watchOS与配对的iOS交互是通过WatchConnectivity框架实现的,包括覆盖式后台传输、队列式后台传输、文件传输、消息传输、消息数据传输、功能栏传输等多个交互类型。

8章健康,Apple Watch提供强大和全面的健康监测功能,如心率、步数、活动能量消耗等,同时会将监测到的数据发送到iPhone上的健康库中。上述的每一个部分在详细讲解的基础上,均提供了案例代码。

2018-11-20 14:17:19 liu_jiuyang 阅读数 120

本节内容转载于
http://www.swift51.com/swift4.0/chapter2/13_Inheritance.html

本页包含内容:

定义一个基类
子类生成
重写
防止重写
一个类可以继承另一个类的方法,属性和其它特性。当一个类继承其它类时,继承类叫子类,被继承类叫超类(或父类)。在 Swift 中,继承是区分「类」与其它类型的一个基本特征。

在 Swift 中,类可以调用和访问超类的方法,属性和下标,并且可以重写这些方法,属性和下标来优化或修改它们的行为。Swift 会检查你的重写定义在超类中是否有匹配的定义,以此确保你的重写行为是正确的。

可以为类中继承来的属性添加属性观察器,这样一来,当属性值改变时,类就会被通知到。可以为任何属性添加属性观察器,无论它原本被定义为存储型属性还是计算型属性。

定义一个基类
不继承于其它类的类,称之为基类。

注意
Swift 中的类并不是从一个通用的基类继承而来。如果你不为你定义的类指定一个超类的话,这个类就自动成为基类。

下面的例子定义了一个叫Vehicle的基类。这个基类声明了一个名为currentSpeed,默认值是0.0的存储属性(属性类型推断为Double)。currentSpeed属性的值被一个String类型的只读计算型属性description使用,用来创建车辆的描述。

Vehicle基类也定义了一个名为makeNoise的方法。这个方法实际上不为Vehicle实例做任何事,但之后将会被Vehicle的子类定制:

class Vehicle {
var currentSpeed = 0.0
var description: String {
return “traveling at (currentSpeed) miles per hour”
}
func makeNoise() {
// 什么也不做-因为车辆不一定会有噪音
}
}
您可以用初始化语法创建一个Vehicle的新实例,即类名后面跟一个空括号:

let someVehicle = Vehicle()
现在已经创建了一个Vehicle的新实例,你可以访问它的description属性来打印车辆的当前速度:

print(“Vehicle: (someVehicle.description)”)
// 打印 “Vehicle: traveling at 0.0 miles per hour”
Vehicle类定义了一个通用特性的车辆类,实际上没什么用处。为了让它变得更加有用,需要完善它从而能够描述一个更加具体类型的车辆。

子类生成
子类生成指的是在一个已有类的基础上创建一个新的类。子类继承超类的特性,并且可以进一步完善。你还可以为子类添加新的特性。

为了指明某个类的超类,将超类名写在子类名的后面,用冒号分隔:

class SomeClass: SomeSuperclass {
// 这里是子类的定义
}
下一个例子,定义一个叫Bicycle的子类,继承成父类Vehicle:

class Bicycle: Vehicle {
var hasBasket = false
}
新的Bicycle类自动获得Vehicle类的所有特性,比如currentSpeed和description属性,还有它的makeNoise()方法。

除了它所继承的特性,Bicycle类还定义了一个默认值为false的存储型属性hasBasket(属性推断为Bool)。

默认情况下,你创建任何新的Bicycle实例将不会有一个篮子(即hasBasket属性默认为false),创建该实例之后,你可以为特定的Bicycle实例设置hasBasket属性为ture:

let bicycle = Bicycle()
bicycle.hasBasket = true
你还可以修改Bicycle实例所继承的currentSpeed属性,和查询实例所继承的description属性:

bicycle.currentSpeed = 15.0
print(“Bicycle: (bicycle.description)”)
// 打印 “Bicycle: traveling at 15.0 miles per hour”
子类还可以继续被其它类继承,下面的示例为Bicycle创建了一个名为Tandem(双人自行车)的子类:

class Tandem: Bicycle {
var currentNumberOfPassengers = 0
}
Tandem从Bicycle继承了所有的属性与方法,这又使它同时继承了Vehicle的所有属性与方法。Tandem也增加了一个新的叫做currentNumberOfPassengers的存储型属性,默认值为0。

如果你创建了一个Tandem的实例,你可以使用它所有的新属性和继承的属性,还能查询从Vehicle继承来的只读属性description:

let tandem = Tandem()
tandem.hasBasket = true
tandem.currentNumberOfPassengers = 2
tandem.currentSpeed = 22.0
print(“Tandem: (tandem.description)”)
// 打印:“Tandem: traveling at 22.0 miles per hour”

重写
子类可以为继承来的实例方法,类方法,实例属性,或下标提供自己定制的实现。我们把这种行为叫重写。

如果要重写某个特性,你需要在重写定义的前面加上override关键字。这么做,你就表明了你是想提供一个重写版本,而非错误地提供了一个相同的定义。意外的重写行为可能会导致不可预知的错误,任何缺少override关键字的重写都会在编译时被诊断为错误。

override关键字会提醒 Swift 编译器去检查该类的超类(或其中一个父类)是否有匹配重写版本的声明。这个检查可以确保你的重写定义是正确的。

访问超类的方法,属性及下标
当你在子类中重写超类的方法,属性或下标时,有时在你的重写版本中使用已经存在的超类实现会大有裨益。比如,你可以完善已有实现的行为,或在一个继承来的变量中存储一个修改过的值。

在合适的地方,你可以通过使用super前缀来访问超类版本的方法,属性或下标:

在方法someMethod()的重写实现中,可以通过super.someMethod()来调用超类版本的someMethod()方法。
在属性someProperty的 getter 或 setter 的重写实现中,可以通过super.someProperty来访问超类版本的someProperty属性。
在下标的重写实现中,可以通过super[someIndex]来访问超类版本中的相同下标。
重写方法
在子类中,你可以重写继承来的实例方法或类方法,提供一个定制或替代的方法实现。

下面的例子定义了Vehicle的一个新的子类,叫Train,它重写了从Vehicle类继承来的makeNoise()方法:

class Train: Vehicle {
override func makeNoise() {
print(“Choo Choo”)
}
}
如果你创建一个Train的新实例,并调用了它的makeNoise()方法,你就会发现Train版本的方法被调用:

let train = Train()
train.makeNoise()
// 打印 “Choo Choo”
重写属性
你可以重写继承来的实例属性或类型属性,提供自己定制的 getter 和 setter,或添加属性观察器使重写的属性可以观察属性值什么时候发生改变。

重写属性的 Getters 和 Setters
你可以提供定制的 getter(或 setter)来重写任意继承来的属性,无论继承来的属性是存储型的还是计算型的属性。子类并不知道继承来的属性是存储型的还是计算型的,它只知道继承来的属性会有一个名字和类型。你在重写一个属性时,必需将它的名字和类型都写出来。这样才能使编译器去检查你重写的属性是与超类中同名同类型的属性相匹配的。

你可以将一个继承来的只读属性重写为一个读写属性,只需要在重写版本的属性里提供 getter 和 setter 即可。但是,你不可以将一个继承来的读写属性重写为一个只读属性。

注意
如果你在重写属性中提供了 setter,那么你也一定要提供 getter。如果你不想在重写版本中的 getter 里修改继承来的属性值,你可以直接通过super.someProperty来返回继承来的值,其中someProperty是你要重写的属性的名字。

以下的例子定义了一个新类,叫Car,它是Vehicle的子类。这个类引入了一个新的存储型属性叫做gear,默认值为整数1。Car类重写了继承自Vehicle的description属性,提供包含当前档位的自定义描述:

class Car: Vehicle {
var gear = 1
override var description: String {
return super.description + " in gear (gear)"
}
}
重写的description属性首先要调用super.description返回Vehicle类的description属性。之后,Car类版本的description在末尾增加了一些额外的文本来提供关于当前档位的信息。

如果你创建了Car的实例并且设置了它的gear和currentSpeed属性,你可以看到它的description返回了Car中的自定义描述:

let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print(“Car: (car.description)”)
// 打印 “Car: traveling at 25.0 miles per hour in gear 3”

重写属性观察器
你可以通过重写属性为一个继承来的属性添加属性观察器。这样一来,当继承来的属性值发生改变时,你就会被通知到,无论那个属性原本是如何实现的。关于属性观察器的更多内容,请看属性观察器。

注意
你不可以为继承来的常量存储型属性或继承来的只读计算型属性添加属性观察器。这些属性的值是不可以被设置的,所以,为它们提供willSet或didSet实现是不恰当。
此外还要注意,你不可以同时提供重写的 setter 和重写的属性观察器。如果你想观察属性值的变化,并且你已经为那个属性提供了定制的 setter,那么你在 setter 中就可以观察到任何值变化了。

下面的例子定义了一个新类叫AutomaticCar,它是Car的子类。AutomaticCar表示自动挡汽车,它可以根据当前的速度自动选择合适的挡位:

class AutomaticCar: Car {
override var currentSpeed: Double {
didSet {
gear = Int(currentSpeed / 10.0) + 1
}
}
}
当你设置AutomaticCar的currentSpeed属性,属性的didSet观察器就会自动地设置gear属性,为新的速度选择一个合适的挡位。具体来说就是,属性观察器将新的速度值除以10,然后向下取得最接近的整数值,最后加1来得到档位gear的值。例如,速度为35.0时,挡位为4:

let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print(“AutomaticCar: (automatic.description)”)
// 打印 “AutomaticCar: traveling at 35.0 miles per hour in gear 4”

防止重写
你可以通过把方法,属性或下标标记为final来防止它们被重写,只需要在声明关键字前加上final修饰符即可(例如:final var,final func,final class func,以及final subscript)。

如果你重写了带有final标记的方法,属性或下标,在编译时会报错。在类扩展中的方法,属性或下标也可以在扩展的定义里标记为 final 的。

你可以通过在关键字class前添加final修饰符(final class)来将整个类标记为 final 的。这样的类是不可被继承的,试图继承这样的类会导致编译报错。

2017-06-29 17:37:06 werctzzz 阅读数 22384

原文链接:http://blog.csdn.net/feng2qing/article/details/73864580

该文章翻译自Apple官方文档: The Swift 4 Programming Language

Guards翻译组 正在翻译Swift 4的全套文档, 这是该文档第二章节《Basic Operators》的上半部分, 第一章节《The Basics》 上半部分请点这里/下半部分请点这里, 原文链接: Basic Operators

翻译 : Stevin三天三夜 (Blog / GitHub)

校对 : Jonhory (简书 / GitHub)

译者心声

我们会不定期的更新翻译文章, Guards翻译组本周内会发布 Basic Operators下半部分 章节中文版. 如感兴趣,可以关注<我们的简书,获取翻译组更多文章>

我们是一群热爱翻译并且热爱 swift 的人, 希望通过自己的努力让不熟悉英语的程序员也能学习到国外的高质量的文章. 如发现文章中翻译错误之处, 烦请跟我们联系, 我们第一时间更正.

想成为我们中一员? 是的, 我们正在招募对翻译感兴趣的小伙伴, 如果你想提高阅读英语文档的水平, 如果你不甘寂寞, 如果你想为广大开发者做点事. QQ:835087646

本篇包含内容:

  • 基本运算符
  • 术语
  • 赋值运算符
  • 算数运算符
  • 求余运算符
  • 一元减号运算符
  • 一元加号操作符
  • 复合赋值运算符
  • 比较运算符
  • 三元条件运算

基本运算符

运算符是检查,改变或合并值的特殊符号和短语。比如:加号(+)是将两个数相加,如 
let i = 1 + 2,和逻辑AND元运算符(&&)结合两两个布尔值,比如:if enteredDoorCode && passedRetinaScan

Swift支持多数标准 C 操作符,并且为了消除常见的编码错误改进了几种特性。例如:赋值运算符(=)没有返回值。防止当使用判等运算符(==)的地方错误地使用它。算术运算符(+-*%等)检测不允许值溢出,来避免保存变量的时候变量取值范围大于或小于其取值范围导致的异常结果。你也可以使用Swift的溢出运算符实现溢出,详见Overflow Operators

Swift还提供了 C 没有的区间运算符,比如:a..<ba...b,快捷地表达了区间内的数值。

本章描述了Swift常见的运算符,Advanced Operators这章涵盖了Swift的高级运算符,并且介绍如何自定义运算符和标准实现运算符自定义类型。

术语

运算符有一元运算符、二元运算符和三元运算符。

  • 一元运算符针对单个对象操作,比如-a,一元运算符分为前置运算符和后置运算符,前置运算符的运算符在对象前面,如!b,后置运算符的运算符在对象后面,如c!.
  • 二元运算符操作两个对象,如2 + 3,是放在中间的,出现在两个运算对象之间。
  • 三元运算符操作三个对象,像C语言一样,Swift只有一个三元运算符,条件运算符a ? b : c.

运算符影响的值叫操作数,在表达式1 + 2中,+是二元运算符,它的两个操作数是12

赋值运算符

赋值运算符(a = b)用b的值初始化或更新了a的值:

let b = 10
var a = 5
a = b
// 此时 a 等于10

如果赋值的右边是一个多元组,那它的元素被分成多个常量或变量:

let (x, y) = (1, 2)
// 此时 x 等于 1,y 等于 2

Swift的赋值操作符不同于 C 和 Objective-C, 它没有返回值,所以下面的代码是错误的:

if x = y {
    // 这是错误的,因为x = y没有返回值
}

这个特性能够防止你使用(==)的时候而错误的写成(=),因为if x = y是无效的,Swift能够帮助你避免这种类型错误的发生。

算数运算符

Swift支持所有数值类型的常见四则运算

  • 加法(+
  • 减法(-
  • 乘法(*
  • 除法(/
1 + 2           // 等于3
5 - 3           // 等于2
2 * 3           // 等于6
10.0 / 2.5      //等于4.0

Swift的算数运算符不同于 C 和 objective-c 的是默认情况下不允许溢出。你可以使用Swift的溢出运算符进行溢出运算(如:a &+ b),详见Overflow Operators.

加法运算符也支持String的拼接

"hello, " + "world"     // 等于 “hello, world”

求余运算符

求余运算符(a % b)计算出b的多少倍恰好合适a并且返回剩余的值(称作余数)

NOTE:
在其他语言中求余运算符也叫做取模运算符,然而严格的来说在Swift中它对负数的操作行为,它是一个余数而非取模。

求余计算的方式,计算9 % 4,你先计算出多少个4恰好适合9

两个4恰好适合9,余数是1(橙色部分显示)

在Swift中表达为:

9 % 4       // 等于1

为了得到a % b的答案,%运算符计算了以下等式并且返回余数作为结果:

a = (b * 倍数) + 余数

当倍数取到最大值的时候乘上b就恰好适合a

94放入等式中

9 = (4 * 2) + 1

相同的方法,可以计算负数

-9 % 4      // 等于-1

-94放入等式可以得到

-9 = (4 * -2) + -1

余数是-1 
对于负数b求余的时候,b的符号会被忽略,意味着a % ba % -b结果是一样的。

一元减号运算符

数值的符号可以切换使用前缀-,称为一元减号运算符

let three = 3
let minusThree = -three         //minusThree等于-3
let plusThree = -minusThree //plusThree等于3,或“负负3”

一元减号(-)直接在操作数之前,中间没有任何空格

一元加号操作符

一元加号操作符(+)只是简单地返回了操作数的值,没有做任何改变

let minusSix = -6
let alsoMinusSix = +minusSix        //alsoMinusSix等于-6

尽管一元加号操作符实际上没有做任何事情,但当你使用一元减号操作符的时候可以使用它来为提供代码提供对称性。

复合赋值运算符

想C一样,Swift也提供把赋值运算符(=)和其他运算符结合起来的复合赋值运算符,比如说其中的*加法赋值运 
算符*(+=

var a = 1
a += 2
a 现在等于 3

表达式a += 2是 a = a + 2的简写,有限地将加法和赋值合成一个运算符同时执行两项任务

NOTE 
复合赋值运算符没有返回值,比如说你不能这样写:let b = a += 2

对了,Swift提供的标准库提供的复合赋值操作符完整列表,详见Swift Standard Library Operators Reference。

比较运算符

Swift支持所有标准 C 语言中的比较运算符

  • 等于(a == b
  • 不等于(a != b
  • 大于(a > b
  • 小于(a < b
  • 大于等于(a >= b
  • 小于等于(a <= b

NOTE 
Swift也提供了恒等(===)和不恒等(!==)两个比较符用于测试两个对象是否引用同一个对象的实例,更多信息详见Classes and Structures.

每个比较运算符都返回了一个布尔值来标识语句是否为真

1 == 1      //为真,因为1等于1
2 != 1      //为真,因为2不等于1
2 > 1       //为真,因为2大于1
1 < 2       //为真,因为1小于2
1 >= 1      //为真,因为1大于或小于1
2 <= 1      //为假,2并不小于或等于1

比较运算符经常用于条件语句,比如if语句

let name = "world"
if name == "world" {
    print("hello, world")
} else {
    print("I'm sorry \(name), but I don't recognize you")
}
// 输出“hello world”,因为name确实等于“world”

更多短语if语句,详见Control Flow 
只要元组中的每个值都相同,你也可以比较相同数量值的元祖。比如:IntString都可以比较,这意味着类型(Int,String)类型的元组可以比较,相反,布尔值不能比较,这意味着包含布尔值的元祖不能比较。 
元组的比较从左到右,每次比较一个值,直到比较发现两个值不相等,比较完这两个值,比较的结果决定了元组比较的总体结果,如果每个元素都相等,那么元组本身也相等,比如:

(1, "zebra") < (2, "apple")   //为真,因为1小于2;“zebra”和“apple”不比较
(3, "apple") < (3, "bird")    //为真,因为3等于3;“apple”小于“bird”
(4, "dog") == (4, "dog")      //为真, 因为4等于4;"dog"等于"dog"

在上面的示例中,第一行左右比较的行为,因为1小于2,就决定(1, "zebra")小于(2, "apple"),而不去考虑元组中的其它值,”zebra“不小于”apple“并不重要,因为元祖的第一个元素已经决定了比较结果,然而,当元组的第一个元素相同的时候,就像第二行和第三行一样,比较他们的第二个元素。

NOTE 
Swift标准库包含了少于7个元素的元组比较运算符,七个或更多元素的元祖比较时,你必须自己实现比较运算。

三元条件运算

三元条件运算符的特殊性在于它有三部分操作数,像:问题 ? 答案1 : 答案2,这个基于问题真或假决定两个表达式中选出一个的简洁操作。如果问题为真,则返回值为答案1,否则,返回值为答案2
三元条件操作符简短地描述了下面的代码

if question {
    answer1
} else {
    answer2
}

这有一个计算表行高的例子,如果有表头,行高应该高于内容50像素,如果没有表头,高于内容20像素。

let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
// 行高等于90

前面的例子要比下面的代码简洁

let contentHeight = 40
let hasHeader = true
let rowHeight: Int
if hasHeader {
    rowHeight = contentHeight + 50
} else {
    rowHeight = contentHeight + 20
}
// 行高等于90

第一个例子使用了三元条件运算符一行代码就能算出rowHeight,这比第二个例子的代码更简洁。 
三元条件运算符为需要考虑的两个表达式提供了高效的简写,然而,使用三元条件运算符也需要谨慎。过度使用会导致简洁的代码变的很难读懂。避开的一个组合语句中使用多个三元条件运算符的情况。

 

2015-11-21 20:15:00 weixin_30552635 阅读数 2

Swift语言是苹果在2014发布的,而且苹果力推开发者使用其来开发APP。所有在此提供一套Swift2.0中文手册供大家使用

:!Swift 2.0 中文手册.pdf

swift 中布局十分严格 切记要注意   左右一定要对称

 

使用注意:

  • 1.语句末尾不用使用 ;
  • 2.在 Swift 中使用 print() 替代 OC 中的 NSLog
  • 3.在swift中访问属性和调用方法都是通过.来进行的
  • 4.在 Swift 中要实例化一个对象可以使用 类名() 的格式,与 OC 中的 alloc/init 等价
  • 5.OC 中的 [[类名 alloc] initWithXXX],  [类名 类名WithXXX]在 Swift 中通常可以使用 类名(XXX: )找到对应的函数
  • 6.OC 中的 [UIColor redColor] 类方法,在 Swift 中通常可以使用 类名.XXX() 找到对应的函数

1.变量和常量

 

2.类型推导和类型装换

自动推导

  • swift 对数据类型要求异常严格
  • swift能够根据右边的代码,推导出变量的准确类型
  • 如果要指定变量,可以在变量名后使用 : 类型
  • Int类型分为好几种,Int8, Int16, Int32, Int64,因为类型严格,Int8和Int16不能进行运算,所以建议以后开发中都使用Int

 

3.字符串 String

  • 是一个结构体,性能高于NSString
  • String 支持直接遍历
  • String 目前具有了绝大多数 NSString 的功能
  • String和NSString转换方便

     

  • OC定义字符串

    /*:
      OC的字符串:
          NSString *str = @"hello";
          格式化字符串: [NSString stringWithFormat:@"%.02f", 3.14159]
      swift中定义字符串:
          var 变量名 = "hello"
    */
  • 字符串中的常用方法

 

 

4.Optional可选

 

5.if条件分支

6.循环

7.switch

8.数组

9.元组

10.字典

11.枚举

12函数

  • 函数的定义

    func 函数名(形参名1: 形参类型1, 形参名2: 形参类型2, ...) `->` 返回值 {
      // 代码实现
    }
    /*函数如果没有返回值:
          1. 省略
          2. -> Void
          3. -> ()
    
      外部参数名,作用能够方便调用人员更好地理解函数的语义
      带外部参数名的参数列表格式:
          (外部参数名1 形式参数名1: 参数类型1, 外部参数名2 形式参数名2: 参数类型2, ...)*/
    
  • 函数定义和调用

    //: 定义函数
    func sum(a: Int, b: Int) -> Int {
      return a + b
    }
    //: 调用函数, b表示外部参数名
    sum(10, b: 20)
    //: 没有返回值
    func sayHello() -> () {
      print("hello")
    }
    sayHello()
    
  • 外部参数名

    • 在形参名前再增加一个外部参数名,能够方便调用人员更好地理解函数的语义
    • swift2.0默认帮我们生成除第一个参数外的所有外部参数名
//: 为什么有外部参数名呢?
func addStudent(name: String, age: Int, number: Int) {
    print("name = \(name), age = \(age), number = \(number)")
}

//: 如果没有外部参数名,我们很难判断每个参数的作用
//addStudent("liudehua", 54, 53)

//: 有外部参数名,每个参数的作用一目了然,swift2.0默认帮我们生成除第一个参数外的所有外部参数名
addStudent("liudehua", age: 54, number: 53)

//: 指定外部参数名
func addStudent2(stu_name name: String, stu_age age: Int, stu_number number: Int) {
    print("name = \(name), age = \(age), number = \(number)")
}

addStudent2(stu_name: "liudehua", stu_age: 54, stu_number: 53)
  • 函数返回元组类型
    /*:
    在c语言中要返回多个值:
      1.传参数时传入指针,在函数内部修改该指针指向的值
      2.返回一个结构体
      3.返回数组
    */
    //: 在swift中可以通过返回元组来方便的返回多个值
    func getStudent() -> (String, Int, Int) {
      return ("liudehua", 54, 53)
    }
    //: student是一个(String, Int, Int)的元组
    let student = getStudent()
    //: 可以通过.0 .1 来访问
    student.0
    student.1
    //: 函数通过元组返回多个值,并且为元组中的元素取名成,方便调用
    func getStudent2() -> (name: String, age: Int, num: Int) {
      return ("liudehua", 54, 53)
    }
    let student2 = getStudent2()
    student2.name
    student2.age

 

闭包

 

       闭包类似于 OC 中的 Block,是一段预先定义好的代码,在需要时执行

定义

  • 闭包表达式格式:

      { (形参名称1: 形参类型1, 形参名称2: 形参类型2, ...) -> 返回值 `in`
              //要执行的代码
      }
    
    • in 用于区分闭包定义和代码实现

 

    定义闭包

    // 定义闭包
    var closure = { (text: String) -> Void in
    }  

 

 

    调用闭包

    // 调用闭包
    closure("学习闭包")

闭包使用场景(回调)

  • 模拟耗时操作

      // 闭包的使用场景: 回调
      // 在子线程执行完任务后通知调用者
      func loadData(finished: (result: String) -> Void) {
          dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
              print("拼命加载数据: \(NSThread.currentThread())")
    
              dispatch_async(dispatch_get_main_queue(), { () -> Void in
                  print(": \(NSThread.currentThread())")
                  // 通知调用者
                  finished(result: "获取到20条数据")
              })
          }
      }
    
  • 调用

    loadData { (result) -> Void in
      print("网络请求完成: \(result)")
    }

类的定义

  • OC中的类

    OC中一个类包涵.h和.m两个文件
      .h:
          @interface 类名: 父类名
          @end
    
      .m:
          @implement 类名
          @end
    
      实例化类:
          类名 *变量名 = [[类名 alloc] init];
    
  • swift 定义类格式

    • ()里面是空,表示调用类的默认构造函数 = [[类名 alloc] init];
    • swift中访问属性通过点语法来访问, 方法也是通过点语法来调用
    • 继承和OC一样,通过 : 来继承, swift也只有单继承

      class 类名: 父类名 {
            //: 一些属性
            //: 一些方法
        }
      
        实例化一个类:
        var 变量名 = 类名()
      
      注意:
        1swift的继承和oc一样是通过:, swift也只有单继承
        2.访问类的属性和调用类的方法都是通过.来进行的
        3.覆盖父类方法, 需要加关键字 override
      
  • 定义Person类:

    //: 定义一个类, 没有继承任何类的类,称之为 基类,超类
    class Person: NSObject {
      // 名称属性
      var name = "liudehua"
      // 年龄
      var age = 54
      // 身高
      var height = 1.78
      // 体重
      var weight = 70.0
      // 方法
      func sleep() {
          print("累了,睡觉")
      }
      func eat() {
          print("饿了,吃饭")
      }
    }
    
  • 实例化Person

    // 实例化类Person
    var p = Person()
    // 访问属性
    print(p.name)
    // 修改属性
    p.name = "zhangsan"
    print("名称修改后:\(p.name)")
    // 调用方法
    p.sleep()
    
  • 定义Student继承Person

    //: 继承 和OC 一样通过 : 来实现继承
    class Student: Person {
      // 班级属性
      var grade = "ios05期"
    
      // 定义学习方法
      func study() {
          print("开开心心学习,高薪就业")
      }
    
      // 覆盖父类方法, 需要加关键字 override
      override func sleep() {
          print("学习累了,睡觉")
      }
    }
    
  • 实例化Student 

    // 实例化Student
    let s = Student()
    print(s.grade)
    // 调用Student的sleep
    s.sleep()

类的属性

  • oc中的属性:
    • @property(noatomic, copy) NSString *name;
      • 1.在.h声明 getter 和 setter 方法
      • 2.在.m实现 getter 和 setter 方法
      • 3.在.m生成 _成员变量
  • 存数型属性: 存储数据
    • 属性监视器: 当存储型属性发生改变的时候,通知我们属性发生了改变
      • willSet: 在属性将要发生改变时调用
      • didSet: 在属性已经发生改变时调用
  • 计算型属性: 不存储任何数据,通过get方法来返回一个计算好的数据通过set方法来设置一个存储型属性的值,当只提供get方法时,称之为只读计算属性.必须要有get方法

    • 计算型属性 相当于 OC 中的 @property 生成的 getter 和 setter 方法,只不过 setter 方法没有给 _成员变量 赋值

        @interface Person ()
      
        @property (nonatomic, assign) CGFloat heightCM;
      
        @end
      
        @implementation Person
      
        // getter
        - (CGFloat)heightCM {
            return ;
        }
      
        // setter
        - (void)setHeightCM:(CGFloat)heightCM {
            // 没有 _heightCM = heightCM
        }
      
  • 类属性: 不管创建多少个实例,都共享这个属性

    • 定义:在类属性前面加class关键字,类属性只能是计算型属性
    • 访问方法: 类名.属性名

存储型属性、计算型属性

class Person {
  //: 存储型属性
  var name = "liudehua"
//
  //: 存储型属性,单位是m
  var height = 1.74
//
  //: 计算型属性
  var heightCM: Double {
      get {
          return height * 100
      }

      set {
          height = newValue / 100
      }
  }
//
  //: 存储型属性
  var age = 54
//
  //: 存储型属性
  var weight: Float = 70 {
    //: 在属性将要发生改变时调用 willSet { print("weight willSet") }     //在属性已经发生改变时调用 didSet { print("weight didSet") } } // //: 定义一个sleep方法 func sleep() { print("person 累了, sleep...") } // //: 定义一个eat方法 func eat() { print("person 饿了, eat...") } } // 实例化Person var person = Person() person.height person.heightCM = 178 person.height person.weight = 72 var person2 = Person() //: person的weight属性和person2的weight没有关系,相互独立的. person2.weight = 60 print(person2.weight)

类属性

//: 定义圆
class Circle {
  //: 只要是圆就有圆周率,圆周率的值固定不变,不管创建多少个实例,都共享这个圆周率属性
  //: 类型属性: 只读计算型属性
  class var pi: Double {
      return 3.141592653
  }
//
  var radius = 20.0
//
  //: 周长,只读计算型属性
  var perimeter: Double {
      return 2 * Circle.pi * radius
  }
}
//
//Circle.pi = 1
//
var pingpong = Circle()
pingpong.perimeter
//
pingpong.radius = 40
pingpong.perimeter

构造函数

自定义 Car 对象

class Person {
    var name: String
}
  • 以上代码会报:“存储性属性没有初始化值”,原因是在swift中类实例化后,所有的存储型属性必须有值

  • 解决方法1:定义属性时赋值

    class Person {
      // 直接赋值
      var name: String = "liudehua"
    }
    // 实例化
    var p1 = Person()
    p1.name
    // 实例化
    var p2 = Person()
    p2.name
    //: 实例化出来对象 name属性都一样,显然不合理.
    
  • 解决方法2:将对象属性类型设置为 Optional
    class Person {
      var name: String?
    }
    var p = Person()
    p.name = "liudehua"
    print(p.name)
    //: 用可选的,打印出来都带Optional
    
  • 输出结果:Optional("liudehua")
  • 有没有什么办法,在类的实例化过程中,给存储型属性设置指定的值?,实例化后直接拿来用.或者在类实例化时指定存储型属性的值

利用 init 函数为属性初始化

  • 在swift中对象是通过构造函数来实例化的.构造函数的作用:在对象实例化过程中给所有的存储型属性设置初始值,并且执行必要的准备和初始化任务.
class Person: NSObject {
   var name: String

    var age: Int

    //: 重写父类构造函数
    override init() {
        print("init")
        name = "liudehua"
        age = 22
    }
}

重载构造函数

  • swift 中支持函数重载,同样的函数名,不一样的参数类型
//: 重载构造函数
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

子类构造函数

  • 自定义子类时,需要在构造函数中,首先为本类定义的属性设置初始值
  • 再调用父类的构造函数,初始化父类中定义的属性
  • 如果子类没有去实现构造函数,会继承父类的构造函数
  • 如果子类实现了构造函数,不会继承父类的构造函数
class Stuent: Person {
    var grade: String

    // 子类构造函数需要调用父类构造函数
    // 需要先初始化子类属性,在调用父类构造函数
    init(name: String, age: Int, grade: String) {
        self.grade = grade
        super.init(name: name, age: age)
    }
}

convenience 构造函数

便利构造函数: 它是辅助性的构造函数.方便创建对象

  • 默认情况下,所有的构造函数都是指定构造函数 Designated
  • convenience 关键字修饰的构造方法就是便利构造函数
  • 便捷构造函数可以返回 nil
  • 需要调用本类的一个指定构造函数
    /// 方便创建ios05期学生
    convenience init?(stuName: String, stuAge: Int) {

        // 判断age是否合法
        if stuAge < 0 || stuAge > 130 {
            print("年龄不合法")
            return nil
        }

        self.init(name: stuName, age: stuAge, grade: "ios05期")
    }

构造函数小结

  • 1.不需要func关键字.名称是固定的,都叫 init
  • 2.当类没有实现构造函数时,系统会添加一个默认的构造函数.
  • 3.如果实现了构造函数,系统就不会添加默认构造函数
  • 4.如果子类没有实现构造函数.会继承父类的构造函数
  • 5.子类构造函数需要调用父类构造函数
  • 6.需要先初始化子类属性,在调用父类构造函数
  • 7.子类一旦实现了构造函数.就不会继承父类的构造函数

懒加载

在 iOS 开发中,懒加载是无处不在的

  • 方法1

    lazy var p = Person()
    
  • 方法2

    // 方法2, 需要指定p的类型
    lazy var p: Person = {
      let person = Person()
      return person
    }()
    
  • 测试调用

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
      p.name = "lisi"
      print("p.name: \(p.name)")
    }
    
  • Person 类

    class Person: NSObject {
      var name: String?
    
      override init() {
          print("初始化")
      }
    }
 

 

转载于:https://www.cnblogs.com/YRFios/p/4984645.html

没有更多推荐了,返回首页