附上资料地址:w3cschool-Swift 教程 、Swift中的关键字详解html
class
:声明一个类,或者类方法class Person: NSObject {
//声明一个实例方法
func run() {
print("run")
}
//class修饰表示:声明一个类方法
class func work() {
print("work")
}
}
复制代码
struct
:声明结构体,内部能够声明成员变量、成员方法。所以更接近于一个类,能够说是类的一个轻量化实现//声明:
struct Person {
var name:String
var age:Int
func introduce(){
print("我叫:\(name),今年\(age)岁")
}
}
//调用:
var person = Person(name: "xiaoMing",age: 20)
person.introduce()
//输出:
我叫:xiaoMing,今年20岁
复制代码
struct
和 class
比较struct是结构体,class是类
一、struct是值类型,class是引用类型;意思是:声明一个新的变量指向这个结构体,改变某个属性,本来的结构体属性不会发生变化;而类会随着改变
`
代码示例:
struct myStru {
var width = 200
}
class myClass {
var width = 200
}
//调用
var stu = myStru()
var stu2 = stu
stu2.width = 300
print(stu.width,stu2.width)
//200 300
var cls = myClass()
var cls2 = cls
cls2.width = 300
print(cls.width,cls2.width)
//300 300
`
二、struct不能被继承,class能够被继承
三、用let修饰class对象,可以修改类的值;若要修改struct的值,要用var来修饰
四、struct是放在栈上,class是放在堆上,所以struct的访问速度更快
五、struct里面若是想声明一个func来修改声明的属性,须要添加关键字mutating,才能编译成功;而class不须要
六、全部的struct都有一个自动生成的成员构造器,而class须要本身生成
七、在struct中,成员变量能够没有初始值;但在class中,若是成员变量没有初始值,就必须为它写一个构造函数
复制代码
static
:声明静态变量或者函数,它保证在对应的做用域当中只有一份, 同时也不须要依赖实例化。若是用于修饰函数,表示类方法,且不能被重写class Person: NSObject {
var name: String
//类方法,而且该方法不能被子类重写
static func run() {
print(self.name + "running")
}
}
复制代码
static
和 class
比较都是放在`func`前面用于指定类方法,只不过`static`修饰的类方法不能够被重写
复制代码
typealias
:各种起别名//声明
typealias abc = Int
//调用
let a:abc = 100
复制代码
enum
:枚举,一种常见的数据类型。好处:使用枚举能够防止用户使用无效值,同时该变量可使代码更加清晰。//写法1,默认赋值0、一、二、3
enum Orientation1:Int{
case East
case South
case West
case North
}
//写法2
enum Orientation2:Int{
case East,South,West,North
}
//调用 具体的值
print(Orientation1.East.rawValue,Orientation1.South.rawValue,Orientation2.West.rawValue,Orientation2.North.rawValue)
//打印
0 1 2 3
复制代码
extension
:拓展,相似oc中的category
分类,可是比分类更增强大。通常用于:
//给person类添加一个run方法
class Person: NSObject {
var name = "swift"
}
extension Person{
func run() {
print(self.name + "running")
}
}
//调用
let per = Person()
per.run()
复制代码
subscript
:下标脚本,可让 结构体
、枚举
、类
使用下标功能。须要注意:subscript
中能够没有set
方法,可是要有get
方法struct Person {
var age = 0
var no = 0
subscript(index: Int) -> Int {
set {
if index == 0 {
age = newValue
} else {
no = newValue
}
}
get {
if index == 0 {
return age
} else {
return no
}
}
}
}
var p = Person()
p[0] = 10
p[1] = 20
print(p.age) // 10
print(p[0]) // 10
print(p.no) // 20
print(p[1]) // 20
复制代码
传多个参数的例子:swift
class Matix {
var data = [
[0,0,0],
[0,0,0],
[0,0,0]
]
subscript(row: Int , col: Int) -> Int {
set {
//守卫,不在这个范围以内的就return
guard row >= 0 && row < 3 && col >= 0 && col < 3 else {
return
}
data[row][col] = newValue
}
get {
guard row >= 0 && row < 3 && col >= 0 && col < 3 else {
return 0
}
return data[row][col]
}
}
}
//调用
var m = Matix()
m[1, 1] = 3
m[0, 1] = 4
//这个超出范围,直接return了
m[4, 4] = 9
print(m.data)
//打印
[[0, 4, 0], [0, 3, 0], [0, 0, 0]]
复制代码
init
:构造函数,初始化方法class PerSon: NSObject {
//若是不给属性直接赋一个初始化值,就必须声明构造函数
var name:String
init(name : String) {
self.name = name
}
}
//调用
let person = PerSon.init(name: "xiaoMing")
print(person.name)
//简写
let per = PerSon(name: "xiaoHong")
print(per.name)
复制代码
deinit
:析构函数,释放方法。与oc中的dealloc
同样,用于:对象的销毁、KVO移除、通知移除、NSTimer销毁数组
protocol
:协议markdown
fallthrough
:穿透,在switch中,执行完当前case,继续向下执行下一个case//写法1 = 写法2
let num = 100
//写法1
switch num {
case 100:
fallthrough
case 200:
print("100 + 200")
default:
print("no")
}
//写法2
switch num {
case 100,200:
print("100 + 200")
default:
print("no")
}
复制代码
where
:筛选条件用的,适用于do-catch
、switch
、for-in
、泛型
、协议
等let array = [100,-50,36,-8,45]
//遍历数组,只有值大于40的才打印
for i in array where i > 40 {
print(i)
}
//打印
100
45
复制代码
is
:类型检查操做符,检查一个实例是否属于一个特定的子类,是返回true,不是返回false// 1.定义数组
let array : [Any] = [12, "zhangsan"]
// 2.取出数组中的第一个
let objcFirst = array.first!
// 3.判断第一个元素是不是一个Int类型
if objcFirst is Int {
print("是Int类型")
} else {
print("非Int类型")
}
复制代码
as
:类型转换操做符,向上转型,从派生类转换成基类//自己根据值定义的是int类型,经过as转换成float类型
var number = 1 as Float
print(number) //1.0
var number = 1 as Float
至关于
var number = Float(1)
复制代码
as!
:向下转型,转成其子类类型,属于强制转型,若是转换失败会报错闭包
as?
:规则跟as!
同样,若是转换失败,会返回一个nil对象异步
// 1.定义数组
let array : [Any] = [12, "zhangsan"]
// 2.取出数组中最后一个元素
let objcLast = array.last!
// 3.转成真正的类型来使用
// as? 将Any转成可选类型,经过判断可选类型是否有值,来决定是否转化成功了
let name = objcLast as? String
print(name) // 结果:Optional("zhangsan")
// as! 将Any转成具体的类型,若是不是该类型,那么程序会崩溃
let name2 = objcLast as! String
print(name2) // 结果:zhangsan
复制代码
convenience
:便利构造函数,用于修饰构造方法init
,一般用于对系统类的init构造方法
进行扩充,特色:async
convenience
一般写在extension
中init
以前添加convenience
convenience
中须要明确调用self.init()
/*
对系统的init进行扩充,
而且这个方法是公共的,
若是子类要修改,就须要先实现父类方法,不能直接重写
*/
required convenience public init(...) {
...
self.init()
...
}
复制代码
required
:只用于修饰类的init
初始化方法,表示该初始化方法是必须实现。要求子类必须实现父类的初始化方法使用规则:ide
required init
方法,这时不能用override
,要一样使用required
修饰required init
方法//子类异于父类init方法状况
class PerSon: NSObject {
var name: String
//若是子类要自定义init方法,要先实现父类的
required init(name: String) {
self.name = name
}
}
class Student: PerSon {
var age: Int = 0
//先实现父类的
required init(name:String) {
super.init(name: name)
}
//再进行自定义init
init(firstName: String, age:Int) {
self.age = age
super.init(name: firstName)
}
}
复制代码
mutating
:在结构体或者枚举中,放在func前,表示可修改它所属的实例及实例属性的值。用于在内部成员方法中修改为员变量的值//正常状况
struct myStruct1 {
var num1 = 100
var num2 = 200
var num3 = 300
}
var stu1 = myStruct1()
print(stu1.num1)//100
//直接修改为员变量的值
stu1.num1 = 999
print(stu1.num1)//999
//经过内部方法改变值
struct myStruct2 {
var num1 = 100
var num2 = 200
var num3 = 300
mutating func changeNum(mark:Int) {
self.num1 += mark
}
}
//调用
var stu2 = myStruct2()
print(stu2.num1)//100
//经过调用结构体的成员方法来修改为员变量的值
stu2.changeNum(mark: 99)
print(stu2.num1)//199
复制代码
lazy
:懒加载,修饰变量,只有在第一次调用的时候才去初始化值lazy var first = NSArray(objects: "1","2")
复制代码
override
:重写父类的方法函数
final
:能够用来修饰class
、func
、var
,表示不可重写。能够将类或者类中的部分实现保护起来,从而避免子类破坏oop
inout
:将值类型的对象 用 引用的方式传递,意思是能够修改外部变量
func test(num: inout Int){
//若是不加inout,改变外部变量会报错
num += 1
}
var a = 10
//调用的时候,是取地址操做
test(num: &a)
print(a)//11
复制代码
defer
:延迟执行,修饰一段函数内任一段代码,使其必须在函数中其余代码执行完毕,函数即将结束前调用;若是有多个defer
会自下而上的顺序执行func test(){
print("函数开始")
defer{
print("执行defer1")
}
print("函数将结束")
defer{
print("执行defer2")
}
defer{
print("执行defer3")
}
}
//调用
test()
//打印
函数开始
函数将结束
执行defer3
执行defer2
执行defer1
复制代码
添加异步线程的状况
func test(){
print("函数开始")
defer{
print("执行defer1")
}
defer{
print("执行defer2")
}
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
print("异步执行完毕")
}
print("函数将结束")
defer{
print("执行defer3")
}
}
test()
//打印:
函数开始
函数将结束
执行defer3
执行defer2
执行defer1
异步执行完毕
结论:
异步代码的执行,不会影响defer的执行时间。事实上,defer的执行只和其所在的做用域有关,若是做用域即将被回收,那么会在回收以前执行defer。
复制代码
throws
:放在可能会出现异常或者错误的函数后面,会把发生的错误带出来,在调用的时候进行错误处理,节省了维护成本;通常调用的时候会配合try
、do-catch
一块儿使用代码示例:
//错误类型枚举
enum MyError : Error {
case ErrorOne
case ErrorTwo
case ErrorOther
}
//使用:关键字所在的位置
func thisFuncCouldThrowError(_ type: Int) throws -> String{
if type == 1 {
return "成功"
}else if type == 2{
throw MyError.ErrorTwo
}else{
throw MyError.ErrorOther
}
}
//调用,配合do-catch进行异常捕捉,抛出异常的方法在调用前要加 try 关键字
do {
let stu = try thisFuncCouldThrowError(20)
print("若是出现错误,这里的代码就不会执行了")
print(stu)
} catch let err as MyError/* 这里若是捕捉到的错误,属于自定义枚举的值,就进行相关处理*/{
print("出现了错误")
print(err)
} catch {
//这里必需要携带一个空的catch 否则会报错。 缘由是可能遗漏
}
//打印
出现了错误
ErrorOther
复制代码
rethrows
:异常往上传递的关键字,针对的不是函数或者方法的自己,而是它携带的闭包类型的参数,当它的闭包类型的参数throws的时候,咱们要使用rethrows继续将这个异常往上传递, 直到被调用者使用到。这相比throws多一个传递的环节//throw函数做为闭包参数传入
//throws
func thisFuncCouldThrowError(_ type: Int) throws -> String{
if type == 1 {
return "成功"
}else if type == 2{
throw MyError.ErrorTwo
}else{
throw MyError.ErrorOther
}
}
//rethrows
func thisFuncRethrows(_ throwsError:(Int) throws -> String) rethrows{
do {
let stu = try throwsError(20)
print("若是出现错误,这里的代码就不会执行了")
print(stu)
} catch let err as MyError{
throw err //这里进行了 再次throw
} catch{
}
}
//调用
let afunc = self.thisFuncCouldThrowError
do {
try self.thisFuncRethrows(afunc)
print("没有错误,若是出现错误,这里的代码就不会执行了")
} catch let err as MyError {
print("出现了错误")
print(err)
}catch{
//这里必需要携带一个空的catch 否则会报错。 缘由是可能遗漏
}
复制代码
swift中提供了5种访问控制的权限: 由低到高:private
、fileprivate
、internal
、public
、open
private
:只能在当前类class中访问、extension修饰的拓展类中能够访问,可是子类及其余类不可访问fileprivate
:只能在当前源文件中访问。也就是说不一样文件中的子类也没法访问internal
:默认的访问级别。在源代码所在的整个模块均可以被访问public
:能够被任何人访问,在本模块中能够被override(重写)和继承,但在其余的模块中不能够被override和继承open
:能够被任何人使用,包含override和继承