This column will continue to update – please iOS friends pay attention!

(The answer is not unique, just for reference,)

1. What about Swift?

Swift is a new programming language released by apple at WWDC in June 2014. It borrows features from JS,Python,C#,Ruby and other languages. It looks a little scripted, but Swift still supports the cocoa touch framework

His strengths:

  1. Swift is more secure, it’s a type-safe language.
  2. Swift is easy to read, with simple syntax and file structure.
  3. Swift is easier to maintain and has a cleaner structure after file separation.
  4. Swift code is less, concise syntax, can eliminate a lot of redundant code
  5. Swift is faster and has higher computing performance.

2. How do Swift and OC call each other?

  • Swift calls OC code

    I need to create aTarget-BriBridging-Header.hBridge file, in the Joe file import need to call OC on behalf of the dock file
  • OC Calls the Swift code

    Direct importTarget-Swift.hIf Swift needs to be called by OC, it needs to decorate its methods or properties with @objc

What’s the difference between a class and a struct?

In Swift, a class is a reference type (pointer type) and a struct is a value type

Value types

  • Value types are copied when passed and assigned; If you assign values to var, let, or pass parameters to a function, you will copy all the contents directly. It is similar to copying and paste operations on a file to produce a new copy of the file. This is a deep copy
  • Value types, such as structs and enumerations, are stored and operated on the stack space

Reference types

  • Reference types use only one “pointer” to the reference object; Assigning a value to a var, let, or function makes a copy of the memory address, similar to making a surrogate file (shortcut, link) that points to the same file. It’s a shallow copy.
  • Reference types, such as Class, are stored and operated on the heap space

4. Compare class and struct.

Classes have the following functions; structs do not:

  1. Classes can inherit, and subclasses can use the properties and methods of their parent classes
  2. A cast can examine and interpret an instance object at run time
  3. Classes can be deinit to free resources
  4. A class can be referenced more than once

The advantage of struct:

  1. Structs are smaller, suitable for replication operations, and safer than having a class instance referenced multiple times
  2. There is no need to worry about memory leaks

5. What is Optional in Swift?

  • In Swift, selectability is used to express the case where a variable is empty. When a variable is empty, its value is nil
  • Put a question mark after the type name? To define a lectotype
  • Either a value type or a reference type can be a lectotype
var name: String? // Default to nil var age: Int? Print (name, age) // print nil, nilCopy the code

6.Swift, what is generics?

  • Generics are designed to increase the flexibility of code. They can be variables or methods whose corresponding code satisfies any type.
  • Generics can parameterize types, increase code reuse, and reduce code volume
Func swap<T>(a: inout T, b: inout T) {(a, b) = (b, a)}Copy the code

7. What is the difference between open, public, internal, fileprivate, private?

There are five levels of access control in Swift, which are open, public, internal, Fileprivate and private in descending order

They follow the basic rules: high-level variables are not allowed to be defined as member variables of low-level variables. For example, a private class may contain public String values, whereas low-level variables can be defined in high-level variables.

  • Open: A class decorated with the highest access permission can be accessed and overridden in any module.
  • Public: the permission is second only to open. The only difference between open and public is that other modules are not allowed to inherit or rewrite
  • Internal: a default permission that is allowed only in the current module and can be inherited and overridden, but not in other modules
  • Fileprivate: A decorated object that is only accessible within the current file;
  • Private: specifies the lowest level of access, allowing access only within the defined scope

8. Keyword :Strong,Weak,Unowned Difference?

  • The memory management mechanism of Swift is the same as that of OC. Strong, and Weak are used in the same way as OC
  • Unowned(no primary reference), no strong references will be generated, and the instance address will be retained (similar to unsafe_unretained in OC). Attempts to access the instance without a primary reference will result in a runtime error (wild pointer).

9. How do I understand copy-on-write?

Value types (such as struct). When copied, the copied object and the original object actually point to the same object in memory. A new object is created in memory only if and when the copied object is modified.

  • In order to improve performance, Struct, String, Array, Dictionary, and Set adopt Copy On Write technology
  • For example, a copy operation is performed only when a write operation is performed
  • Swift ensures optimal performance for assigning to library value types, so there is no need to avoid assigning in order to guarantee optimal performance

10. What is attribute observation?

Attribute observation refers to monitoring and responding to attribute attributes within the current type. Attribute observation is a feature in SWIFT and has two types, willSET and DIDSET

var title: String {
    willSet {
        print("willSet", newValue)

    }
    didSet {
        print("didSet", oldValue, title)
    }
}
Copy the code
  • The willSet will pass the newValue, which is called newValue by default
  • DidSet passes the oldValue, oldValue by default
  • Setting property values in initializers does not trigger willSet and didSet

More: iOS interview materials

11. Why does Swift design String,Array, and Dictionary as value types?

  • Value types operate on the stack, and reference types operate on the heap. The stack operation is simply the movement of a single pointer, while the heap operation involves merging, shifting, and relinking. Swift is designed in this way to reduce the number of times that memory is allocated and recycled on the heap Copy-on-write minimizes the cost of value passing and replication

12. How to make some methods of the Protocol in Swift optional?

  • Add in front of the protocol and method@objc, and then add in front of the methodoptionalThe key word is to change the protocol to OC
@objc protocol someProtocol {
  @objc  optional func test()
}
Copy the code
  • Use extensions to specify optional methods. In SWIFT, protocol extensions can define default implementations of some methods
protocol someProtocol {
    func test()
}

extension someProtocol{
    func test() {
        print("test")
    }
}
Copy the code

13. What are the differences between init in Swift and OC?

The SWIFT initialization method is more strict and accurate. The SWIFT initialization method needs to ensure that all non-optional variables are initialized. Meanwhile, swfit adds two keywords of convenience and Required to modify the initializer

  • Convenience provides only a convenience initializer and must be initialized by a specified initializer
  • Required forces a child class to override an initialization method decorated in its parent class

14. What are the differences between Swift and OC protocol?

  • The protocol in Swift and OC is similar in that both can be used as proxies.
  • Differences: The protocol in Swift can also abstract the interface and implement protocol-oriented, thus greatly improving the programming efficiency. The protocol in Swift can be used for value types, structures and enumerations.

15. What is the difference between introspection in SWIFT and OC?

Introspection in OC is to determine whether an object belongs to a class operation, there are two ways

[obj iskinOfClass:[SomeClass class]]
[obj isMemberOfClass:[SomeClass class]]
Copy the code

Since many classes in Swift do not inherit from NSObject, Swift uses is to determine whether it belongs to a type. Is applies not only to classes, but also to enums and structs

16. What is function overload? Does Swift support function overloading?

  • Function overload refers to: the function name is the same, the number of parameters of the function is different, or the parameter type is different, or the parameter label is different, the return value type is independent of the function overload
  • Swift supports function overloading

17. What is the difference between associated and original values in enumerations in Swift?

  • Associated values – It is sometimes useful to store the member values of an enumeration with other types of variables

    // Associated Values enum Date {case digit(year: Int, month: Int, day: Int) case string(string)}Copy the code
  • Raw value – Enumeration members can be pre-associated with a default value of the same type, called: raw value

    Enum Grade: String {case perfect = "A" case great = "B" case good = "C" case bad = "D"}Copy the code

18. What does the closure structure look like in Swift?

{(argument list) -> return value type in function body code}Copy the code

19. What is a trailing closure?

  • Take a long closure expression as the last argument to the function
  • Using trailing closures increases the readability of functions
  • A trailing closure is a closure expression that is written outside (after) the function call parentheses
// fn = exec(v1: Int, v2: Int, fn: (Int, Int) -> Int) {print(fn(v1, v2))} 20) {$0 + $1}Copy the code

20. What is an escape closure?

When a closure is passed as an actual argument to a function or variable, we say that the closure escapes, and we can write @escaping before the formal argument to clarify that escaping is allowed.

  • Non-escape closures, escape closures, are generally passed to functions as arguments
  • Non-escaping closures: The closure call occurs before the function ends, and the closure call is within the scope of the function
  • Escaping closures: It is possible for closures to be called after the function has finished. The escaping closure call escapes the scope of the function and needs to be declared via @escaping
// 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 tag the formal argument to the function as @escaping, you will encounter compile time errors.

21. What is an automatic closure?

An automatic closure is a closure that is automatically created to package an expression that is passed to a function as an actual argument. It does not take any actual arguments, and when it is called, it returns the value of the internally packaged expression. The advantage of this syntax is that it allows you to omit the parentheses surrounding the function-form arguments by writing ordinary 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’s best to explicitly comment where @autoclosure is used: this value is deferred
  • @autoclosure will automatically wrap 20 as a closure {20}
  • @Autoclosure only supports () -> T arguments
  • @Autoclosure does not support only the last parameter
  • With @Autoclosure or without @Autoclosure, the function is overloaded

If you want automatic closures to allow escape, use both the @Autoclosure and @escaping flags.

22. What is the difference between storage attributes and computing attributes in SWIFT?

Attributes associated with instance objects in Swift fall into two broad categories

Stored Property

  • Similar to the concept of member variables
  • Stored in the memory of the instance object
  • Structures and classes can define storage properties
  • Enumerations cannot define storage properties

Computed Property

  • The essence is method (function)
  • Does not occupy the memory of the instance object
  • Enumerations, structs, and classes can all define computed properties
Struct diameter {// var radius: Double; Double { set { radius = newValue / 2 } get { return radius * 2 } } }Copy the code

23. What is a Lazy Stored Property?

Use lazy to define a property that is stored lazily and initialized only when the property is first used (similar to lazy loading in OC).

  • The lazy attribute must be var, not let

    • A let must have a 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 a 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

24. What is a property viewer?

You can set a property observer for non-lazy var storage properties, listening for property changes by 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

25. What Type Property does swift have?

Strictly speaking, attributes can be divided into

Instance Property: Can only be accessed through Instance objects

  • Stored Instance Property: Stored in the memory of the Instance object. 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, there will be only one copy of memory (similar to global variables).
  • Computed Type Property

You can define the type attribute p as static or with the keyword class if it is a class

struct Car {
    static var count: Int = 0
    init() {
        Car.count += 1
    }
}
Copy the code

Unlike storing instance properties, you must set an initial value for the storage type properties

  • Because a type does not have an init initializer like an instance object to initialize the storage properties

The storage type attribute is lazy by default and is initialized on the first use

  • Even if it is accessed by multiple threads at the same time, it is guaranteed to initialize only once
  • The storage type attribute can be a let

Enumeration types can also define type properties (store type properties, compute type properties)

26. How to use singleton mode in Swift?

Singletons can be written using the type attribute +let+private; The code is as follows:

public class FileManager { public static let shared = { // .... / /... return FileManager() }() private init() { } }Copy the code

27. What is the subscript in swift?

  • Subscript can be used to add subscript to any type (enumeration, structure, class)
  • The syntax for subscript is similar to instance methods, computed properties, and essentially methods (functions)

Use the following:

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() p[0] = 11.1 p[1] = 22.2 Print (p.y) // 22.2Copy the code

27. Brief description of the initializer in Swift?

  • Initializers can be defined for classes, structs, and enumerations
  • Classes have two types of initializers:Designated Initializer,Convenience Initializer
// Specify initializers init(parameters) {statements} // Specify initializers init(parameters) {statements}Copy the code

Rules:

  • Every class has at least one specified initializer, which is the primary initializer for the class
  • The default initializer is always the specified initializer for the class
  • Classes tend to have a small number of designated initializers. A class usually has only one designated initializer

Rules for mutual invocation of initializers

  • The specified initializer must call the specified initializer from its immediate parent class
  • The convenience initializer must call another initializer from the same class
  • The convenience initializer must eventually call a specified initializer

28. What is the optional chain?

Optional chain is a process of calling and querying optional properties, methods, and subscripts, which may be nil. If the option contains a value, the call to the property, method, or subscript succeeds; If the option is nil, calls to properties, methods, or subscripts will return nil. Multiple queries can be linked together, and if any node in the chain is nil, the entire chain fails gracefully.

  • More than one? You can link them together
  • If any node in the chain is nil, then the entire chain will fail

29. What is Operator Overload?

Classes, structs, and enumerations can provide custom implementations of existing operators. This operation is called operator overloading

Struct Point {var x: Int var y: Int} struct Point {var x: Int Int x: Int} struct Point {var x: Int x: Int} struct Point {var x: Int x: Int} 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

Recommended Reading:Want to enter big factory, interview question essential! (iOS Interview collection!)