final

We know that classes can be inherited, and when we’re writing a class that we don’t want to be inherited by anyone else, we can consider using final

In this way, your class cannot be inherited and modified at will

In addition, we know that Swift method calls are divided into tables of functions,dynamic and static, whereas when we use final, the func\ class tells the compiler that this is the final form, so that the function calls are more efficient.

#waring #error

#waring and #error are keywords introduced in Swift4.2 to replace //TODO: handle more detailed alerts.

# Waring is lighter and compilers can compile

#error Indicates an error

When you’re trying to get down to business and suddenly someone interrupts you and drags you into a meeting? Got an emergency call? And when it’s over, it’s like, what was I doing? In this case, I can write a #error, and when I come back, I can see it immediately

Self

In any class,self is essentially a shorthand for the class instance: In ViewController, we use self for the class instance, rather than the let or Var instance that uses viewController.init everywhere

Value types(Value type) &Reference type(Reference type)

The best example is Value types \ struct All structures are Reference types class All structures are Reference types

Their relationship is like Google Docs and Excel. When you send Excel to a friend, you’re changing a different Excel, but if you share a Link to Google Docs, you’re actually changing one file. We can think of the structure as excel and the class as Google Docs

Q: Why does Swift design String, Array, and Dictionary as value types? A: The biggest advantage of value types over reference types is their efficient use of memory. Value types operate on the stack and reference types operate on the heap. Operations on the stack simply move a single pointer up or down, while operations on the heap involve merging, shifting, relinking, and so on. That is, Swift is designed to dramatically reduce the number of memory allocations and reclaims on the heap. Copy-on-write also minimizes the overhead of value passing and copying.

typealias

Typealias: a new name for an existing type. Typealias actually has many elaborate usage scenarios in Swift

Codable is actually a TypeAlias

 public typealias Codable = Decodable & Encodable
Copy the code

We can also create a UITableViewDelegate and UITableViewDataSource

typealias TableViewMethod = UITableViewDelegate & UITableViewDataSource
Copy the code

Use scenario 2 to customize a String alias

typealias DogName = String
typealias Owner = String

func printDog(owner : Owner,dogName : DogName){
    print("\(dogName) is \(owner)'s dog")
}
printDog(owner: "Billy", dogName: "Lucky")

Copy the code

Using Scenario 3, which is the most common use, define a Closure so that we don’t have to rewrite the Closure expression everywhere.

typealias Action = (()-> Void)
Copy the code

Lazy

Lazy loading

For example,

struct Calculator { static func calculateGamePlayed() -> Int { var game:[Int] = [] for i in 1... 4_000 { game.append(i) } return game.last! }} / / : [Next](@next) struct Player { var name:String var team:String var position:String var gamesPlayed = Calculator.calculateGamePlayed() // var gamesPlayed :Int { // return Calculator.calculateGamePlayed() // } lazy var introduction = { return "now enter the game\(name)" }() } var jordan = Player.init(name: "M", team: "Bulls", position: "new") print(jordan.introduction)Copy the code

When we get the property directly for the method, we can see that it’s going to happen 4000 times even if it’s not called, and the class has evaluated the property once when it’s initialized, but we don’t really need it, we want to load it lazily for performance reasons

    lazy var gamesPlayed = Calculator.calculateGamePlayed()
Copy the code

PS. Note that lazy loading, while useful, is unsafe in multithreaded situations