What does the closure structure look like in SWIFT
{(parameter list) -> Return value type in function body code}Copy the code
What is a trailing closure
Take a long closure expression as the last argument to the function
A trailing closure is a closure expression written outside (after) the function call parentheses
Func exec(v1: Int, v2: Int, fn: (Int, Int) -> Int) {print(fn(v1, v2))} 20) {$0 + $1}Copy the code
Escaping Closure What escaping closure is when a closure is passed to a function or variable as an actual argument, we say that the closure escaped. To clarify that escaping is allowed, we write @escaping before the formal argument.
- Non-escape closures, escape closures, are generally passed to functions as arguments
- Non-escaping closures: Closure calls occur before the end of a function, and the closure calls are in function scope
- Escaping closure: It is possible for a closure to be called after a function ends. Closure calls that escape the scope of a function are required with the @escaping declaration
// Define an array to store the closure type var completionHandlers: [() - > Void] = [] / / closures as actual parameters in the method, the storage to the external variable func someFunctionWithEscapingClosure (completionHandler: @escaping () -> Void) { completionHandlers.append(completionHandler) }Copy the code
If you do not mark the function with the formal argument @escaping, you will experience a compile-time error.
What is an automatic closure An automatic closure is a closure that is automatically created to package expressions passed to functions as actual arguments. It takes no actual arguments, and when it is called, it returns the value of the internally packaged expression. The nice thing about this syntax is that it lets you omit the parentheses surrounding functional formal arguments by writing plain expressions instead of explicit closures
func getFirstPositive(_ v1: Int, _ v2: @autoclosure () -> Int) -> Int? {
return v1 > 0 ? v1 : v2()
}
getFirstPositive(10, 20)
Copy the code
- To avoid conflicts with expectations, it is best to make it clear where @Autoclosure is used that this value will be deferred
- @autoClosure will automatically wrap 20 into a closure {20}
- @Autoclosure only supports arguments in () -> T format
- @Autoclosure does not support only the last parameter
- @autoclosure and no @Autoclosure constitute function overloading
If you want automatic closures to allow escape, use both the @autoclosure and @escaping flags.
In Swift, the difference between Stored properties and computed properties Stored Property
- Similar to the concept of a member variable
- Stored in the memory of the instance object
- Structures and classes can define storage properties
- Enumerations cannot define storage properties
Computed Properties (Computed Property)
- The essence is the method (function)
- Does not occupy the memory of the instance object
- Enumerations, structures, and classes can all define computed properties
Struct diameter: struct diameter: struct diameter: Double { set { radius = newValue / 2 } get { return radius * 2 } } }Copy the code
Using Lazy, you can define a Lazy Stored Property that will be initialized the first time the Property is used (similar to Lazy loading in OC).
- The lazy attribute must be a var, not a let
- The let must have the value before the initialization method of the instance object completes
- If multiple threads access the lazy property for the first time
- There is no guarantee that the property will be initialized only once
Class PhotoView {// Lazy var image: image = {let URL = "https://.. x.png" let data = Data(url: url) return Image(data: data) }() }Copy the code
What is a property observer that can set a property observer for a non-lazy VAR storage property to listen for property changes through the keywords willSet and didSet
struct Circle { var radius: Double { willSet { print("willSet", newValue) } didSet { print("didSet", oldValue, Radius)}} init() {self.radius = 1.0 print("Circle init! )}}Copy the code
What Type Property does swift have
-
Instance Property: Can only be accessed from Instance objects
-
Stored Instance Property: Stored in the memory of Instance objects. Each Instance object has one copy
-
Computed Instance Property
-
Type Property: Can only be accessed by Type
-
Stored Type Property: During the entire run of the program, only one portion of memory is Stored (similar to global variables).
-
Computed Type Properties (Computed Type Property)
You can define the type attribute p as static or use the class keyword if it’s a class
struct Car {
static var count: Int = 0
init() {
Car.count += 1
}
}
Copy the code
Unlike store instance properties, you must set initial values for store type properties
Because types don’t have an init initializer to initialize storage properties like instance objects do
The storage type attribute is lazy by default and is initialized the first time it is used
It is guaranteed to be initialized only once, even if accessed by multiple threads at the same time
The storage type attribute can be let
Enumerated types can also define type properties (storage type properties, computed type properties)
How to use singleton pattern in SWIFT can be written by type attribute +let+private singleton; The code is as follows
public class FileManager { public static let shared = { // .... / /... return FileManager() }() private init() { } }Copy the code
Subscript the syntax of subscript is similar to that of instance methods and computed properties. It is essentially a method (function).
Class Point {var x = 0.0, y = 0.0 subscript(index: Int) -> Double { set { if index == 0 { x = newValue } else if index == 1 { y = newValue } } get { if index == 0 { return X} else if index == 1 {return y} return 0}} var p = Point() // 11.1 print(p.y) // 22.2Copy the code
A brief description of initializers in Swift
- Classes, structs, and enumerations can all define initializers
- Class has two initializers: Designated Initializer and Convenience Initializer.
// Init (parameters) {statements} // Easy init(parameters) {statements}Copy the code
Rules:
- Each class has at least one designated initializer, which is the primary initializer of the class
- The default initializer is always the designated initializer for the class
- Classes tend to have a small number of designated initializers, and a class usually has only one
Rules for calling each other to initializers
- The specified initializer must be called from its immediate parent
- The convenience initializer must call another initializer from the same class
- The convenience initializer must eventually call a designated initializer
What optional chain An optional chain is a procedure that calls and queries optional properties, methods, and subscripts, which may be nil. If the option contains a value, the attribute, method, or subscript was called successfully; If the optional is nil, calls to properties, methods, or subscripts return nil. Multiple queries can be linked together, and if any node in the chain is nil, the whole chain fails gracefully
More than one? You can link them together
If any node in the chain is nil, then the whole chain will fail the call
What is Operator Overload? Classes, structs, enumerations can provide custom implementations of existing operators. This operation is called Operator Overload
Struct Point {var x: Int var y: Int static func + (p1: Point, p2: Point) -> Point {return Point(x: Point) p1.x + p2.x, y: p1.y + p2.y) } } var p1 = Point(x: 10, y: 10) var p2 = Point(x: 20, y: 20) var p3 = p1 + p2Copy the code
The above is the full text, I hope to help you
Citation: Original address