1、enum
在 Swift 中,我们使用 enum 关键字去声明枚举。枚举是一种常见的数据类型,他的主要功能就是将某一种有固定数量可能性的变量的值,以一组命名过的常数来指代。比如正常情况下方向有四种可能,东,南,西,北。我们就可以声明一组常量来指代方向的四种可能。使用枚举可以防止用户使用无效值,同时该变量可以使代码更加清晰。比如:

enum Orientation: Int {
    case East
    case South
    case West
    case North
}
print(Orientation.East.rawValue)
/**
 输出结果 0
*/

2、struct
在 Swift 中,我们使用 struct 关键字去声明结构体,Swift 中的结构体并不复杂,与 C语言 的结构体相比,除了成员变量,还多了成员方法。使得它更加接近于一个类。个人认为可以理解为是类的一个轻量化实现。比如:

struct Person {
    var name: String
    var age: Int

    func introduce() {
        print("我叫:\(name), 今年\(age)岁")
    }
}

var person = Person(name: "xiaoMing", age: 20)
person.name = "xiaoMing"
print("person.name = \(person.name)")
person.introduce()

3、final
Swift 中,final 关键字可以在 class、func 和 var 前修饰。表示 不可重写 可以将类或者类中的部分实现保护起来,从而避免子类破坏。详细了解可以去看看(Swift - final关键字的介绍,以及使用场景)比如:

class Fruit {
    // 修饰词 final 表示 不可重写 可以将类或者类中的部分实现保护起来,从而避免子类破坏
    final func price() {
        print("price")
    }
}
    
class Apple : Fruit {    // 类继承
    // 重写父类方法,编译器会报错
    override func price() {
        print("重写父类的price 方法")
    }
}

4、deinit
在 Swift 中,deinit 属于析构函数,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。和 OC 中的 dealloc 一样的,通常在 deinit 和 dealloc 中需要执行的操作有:  

  (1)对象销毁

  (2)KVO移除

  (3)移除通知

  (4)NSTimer销毁
5、extension
在 Swift 中,extension 与 Objective-C 的 category 有点类似,但是 extension 比起 category 来说更加强大和灵活,它不仅可以扩展某种类型或结构体的方法,同时它还可以与 protocol 等结合使用,编写出更加灵活和强大的代码。它可以为特定的 class、strut、enum 或者 protocol 添加新的特性。当你没有权限对源代码进行改造的时候,此时可以通过 extension 来对类型进行扩展。extension 有点类似于 OC 的类别 – category,但稍微不同的是 category 有名字,而 extension 没有名字。在 Swift 中的可以扩展以下几个:

  (1)定义实例方法和类型方法

  (2)添加计算型属性和计算静态属性

  (3)定义下标

  (4)提供新的构造器

  (5)定义和使用新的嵌套类型

  (6)使一个已有类型符合某个接口

比如:

//    添加计算属性
extension Double {
    var km: Double { return self * 1_000.0 }
    var m: Double { return self }
    var cm: Double { return self / 100.0 }
}

class Person {
    var name:String
    var age:Int = 0
    init?(name:String) {
        if name.isEmpty {
            return nil
        }
        self.name = name
    }
}

extension Person {
    //添加方法
    func run() {
        print("走了50公里")
    }
}

let oneInch = 25.4.km
print("One inch is \(oneInch) meters")
/**

输出结果:One inch is 25400.0 meters
*/
let person = Person.init(name: "xiaom")
person?.run()
/**
输出结果:走了50公里
*/

6、protocol
在 Swift 中,protocol 关键字也是属于协议。比如:

protocol PersonProtocol {
    var height: Int { get set }
    var weight: Int { get }
    func getName()
    func getSex()
    func getAge(age: Int)
}

struct Student: PersonProtocol {
    var height = 178
    var weight = 120
    func getName() {
        print("MelodyZhy")
    }
    func getSex() {
        print("boy")
    }
    func getAge(age: Int) {
        print("age = \(age)")
    }
}

 var stu = Student()
let height1 = stu.height
stu.height = 180
print("height1 = \(height1) height2 = \(stu.height)")

/**
输出结果:
height1 = 178 height2 = 180

7、static
Swift中,用 static 关键字声明静态变量或者函数,它保证在对应的作用域当中只有一份,同时也不需要依赖实例化。注意:(用static关键字指定的方法是类方法,他是不能被子类重写的),比如:

class Person {
        
    // 给方法添加class关键字表示创建类方法
    class func work() {
        print("Type Method: Person: 学生.")
    }

    // 使用static关键字创建类方法
    static func ageOfPerson(name: String) {
        print("Type Method: Person name: \(name)")
    }

    // 可以和类方法重名, 以及一样的参数.
    func nameOfPerson(name: String) {
        print("Instance Method: person name \(name)")
    } 
}
    
class Student: Person {
    // 注意 子类Student的实例方法work(), 和父类的类方法work()没有关系, 二者不在同一个级别上, 不存在同名问题.
    func work() {
        print("Instance Method: Student: University Student")
    }
}

8、typealias

在 Swift 中,使用关键字 typealias 定义类型别名(typealias 就相当于 Objective-C 中的 typedef),就是将类型重命名,看起来更加语义化。比如:

typealias Width = CGFloat
typealias Height = CGFloat
func rectangularArea(width: Width, height: Height) -> Double {
    return Double(width * height)
}
let area: Double = rectangularArea(width: 10, height: 20)
print(area)
/**
结果为:200.0
*/

9、override
在 Swift 中,如果我们要重写某个方法,或者某个属性的话,我们需要在重写的变量前增加一个 override 关键字,比如:

class Fruit {
    var sellPrice : Double = 0

    func info() -> () {
        print("fruit")
    }
    // 修饰词 final 表示 不可重写 可以将类或者类中的部分实现保护起来,从而避免子类破坏
    final func price() {
        print("price")
    }
}
    
class Apple : Fruit {    // 类继承
    func eat () -> () {
        print("apple22222")
    }
    // 重写父类方法
    override func info() {
        print("重写父类的info 方法00000")
    }
    // 重写父类的属性或者方法要使用关键字 override 进行修饰
    override var sellPrice: Double {
        get {
            print("kkkkkkk\(super.sellPrice)")
            return super.sellPrice + 3
        }
        set {
            print("qqqqq")
            super.sellPrice = newValue * newValue
        }  
    }  
}  

let app = Apple()
app.info()
app.sellPrice = 20.0
let  adb = app.sellPrice

print("adb == \(adb)")

/**
 输出结果为:
 重写父类的info 方法00000
 qqqqq
 kkkkkkk400.0
 adb == 403.0
*/

10、required
在 Swift 里,required 是用来修饰 init 方法的,说明该构造方法是必须实现的。比如:

class PerSon {
    var name:String
    required init(name : String) {
        self.name = name
    }
}
    
class Student: PerSon {
    required init(name:String) {
        super.init(name: name)
    }
}
从上面的代码示例中不难看出,如果子类需要添加异于父类的初始化方法时,必须先要实现父类中使用 required 修饰符修饰过的初始化方法,并且也要使用 required 修饰符而不是 override。

注意:

 1. required 修饰符只能用于修饰类初始化方法。

 2. 当子类含有异于父类的初始化方法时(初始化方法参数类型和数量异于父类),子类必须要实现父类的required 初始化方法,并且也要使用required 修饰符而不是 override。

 3. 当子类没有初始化方法时,可以不用实现父类的 required 初始化方法。

11、lazy
在 Swift 中,lazy 关键修饰的变量,只有在第一次被调用的时候才会去初始化值(即懒加载)。比如:

lazy var first = NSArray(objects: "1", "2")
注意:用 lazy 修饰的变量必须是用 var 声明的,因为属性的初始值可能在实例构造完成之后才会得到。而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性。如果被 lazy 修饰的变量没有在初始化时就被多个线程调用,那就没有办法保证它只被初始化一次了。

swift 访问级别
open public internal fileprivate private
private :只在当前类中调用 ,不能在extension中调用
fileprivate:可以在当前类中调用 ,在extension和类是在同一个源文件中 也可以在extension中调用
Internal: , 为默认访问级别, 允许实体被定义模块中的任意源文件访问,但不能被该模块之外的任何源文件访问。通常在定义应用程序或是框架的内部结构时使用。
public: 可以在其他作用域中调用 但不能在override中访问,其子类的extension也不能调用
open: 可以在其他作用域中调用 其他作用域被继承或重载 override都可以调用
final:在关键字class 前添加 final (修饰符) 可以将整个类标为 final ,这个样的类不可以被继承,视图继承这样的类会编译报错

1、open
在 Swift 中,open 修饰的对象表示可以被任何人使用,包括 override 和继承。例如:

import UIKit

// 在本类外的范围外可以被继承
open class ParentClass1: NSObject {
    // 这个方法在任何地方都可以被override
    open func abc() {
        print("abc")
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        //这里可以调用module1的方法
        let child = ChildrenClass1.init()
        child.abc()
        /**
         打印结果:abc
         */
    }

    class ChildrenClass1: ParentClass1 {
        
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

2、public
在 Swift 中,public 表示公有访问权限,类或者类的公有属性或者公有方法可以从文件或者模块的任何地方进行访问。但在其他模块(一个 App 就是一个模块,一个第三方 API,第三等方框架等都是一个完整的模块)不可以被 override 和继承,而在本模块内可以被 override 和继承。

import UIKit

// 在module1外的范围外可以被继承
public class ParentClass1: NSObject {
    // 这个方法在任何地方都可以被override
   public func abc() {
        print("abc")
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        //这里可以调用module1的方法
        let child = ChildrenClass1.init()
        child.abc()
        
        /**
         打印结果:abc11
         */
    }

    class ChildrenClass1: ParentClass1 {
        override func abc() {
            print("abc11")
        }
    
        func run() -> Void {
            print("run")
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

3、internal
在 Swift 中,public 表示内部的访问权限。即有着 internal 访问权限的属性和方法说明在模块内部可以访问,超出模块内部就不可被访问了。在 Swift 中默认就是 internal 的访问权限。

import UIKit

// 在module1外的范围外可以被继承
internal class ParentClass1: NSObject {
    // 这个方法在任何地方都可以被override
    func abc() {
        print("abc")
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 这里可以调用module1的方法
        let child = ChildrenClass1.init()
        child.abc()
        
        /**
         打印结果:abc11
         */
    }

    class ChildrenClass1: ParentClass1 {
        override func abc() {
            print("abc11")
        }
    
        func run() -> Void {
            print("run")
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

4、private
在 Swift 中,private 私有访问权限。被 private 修饰的类或者类的属性或方法可以在同一个物理文件中访问。如果超出该物理文件,那么有着 private 访问权限的属性和方法就不能被访问。比如:

import UIKit

// 在module1外的范围外可以被继承
internal class ParentClass1: NSObject {
    // 这个方法在任何地方都不能被 override
     private func abc() {
        print("abc")
    }
}

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 这里可以调用module1的方法
        let child = ChildrenClass1.init()
        child.abc()
        
        /**
         打印结果:abc11
         */
    }

    class ChildrenClass1: ParentClass1 {

        /**
         这里就会报错
         */

        override func abc() {
            print("abc11")
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

5、fileprivate
在 Swift 中,fileprivate 访问级别所修饰的属性或者方法在当前的 Swift 源文件里可以访问。比如:

// 在 module1 外的范围外可以被继承
internal class ParentClass1: NSObject {
    // 这个方法在本 Swift 文件中可以被 override
     fileprivate func abc() {
        print("abc")
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //这里可以调用module1的方法
        let child = ChildrenClass1.init()
        child.abc()
        
        /**
         打印结果:abc11
         */
    }

    class ChildrenClass1: ParentClass1 {

        override func abc() {
            print("abc11")
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}