Those of you who know Swift well know that security is a top priority when Apple promotes Swift. But where does Swift’s security lie? The following is a temporary thought of personal comments, welcome to add.

Type safety

Swift beginners or new to Swift development, there are some slots for Swift, optional type of ‘? ‘,Int and Double cannot be implicitly converted, there is no built-in runtime, etc., but these are the advantages of Swift’s design, or in other words, it is designed to be so.

  • Nil in Objective-C, by default, calls any method without an error, and nil, written in arrays and dictionary literals, crashes.
  • If it is a simple scenario, it may not be obvious enough, but it will be considered convenient.
  • But if it is a complex project, dozens of hundreds of individuals to maintain a large App, provide the interface between various components used by other components, each component method in order to ensure their sound, often to do type test of biography, empty validation, if forget to consider or leave, sometimes will cause some problems, such as the type is wrong, abnormal display, etc.
  • In Swift an Option type minimizes the risk of being null. At any time you can determine whether or not the parameter or attribute you are using is likely to be null. Sometimes it’s nice to write and logical when you get used to it.
  • Just as an Option can only handle nil, so can Swift’s statically compiled feature, its exception capture feature, which together ensure that Swift’s code is certain the moment it’s written. To write a method in Swift, you don’t need to think too much about it, just make sure that the parameters input by the defined method are processed and output.
  • You don’t need to worry about null parameters, you don’t need to worry about whether an Array type will be passed in a String type, you don’t need to worry about the unexpected Crash. In Objective-C, that’s pretty much a luxury.
  • The other reason why Swift is more efficient than OC is because of its concise, protocol-oriented, highly abstract generics.

An unsafe situation

  • Of course, exceptions are not completely out of the question, and there are a few caveats to writing secure Swift code
  • For example, an array is out of bounds, which is also a concern in Swift.
  • Some code that communicates with OC or C++ also needs to be aware of the actual call null exception.
  • Using the underlying pointer manipulation API for Unsafe that Swift provides also requires a lot of care.
  • Swift just calls these apis that can manipulate memory directly and it’s called Unsafe, and it wants us not to use them as much as possible, so it probably avoids the wild pointer situation
  • OC is just a property, accidentally write wrong can lead to wild pointer.

Memory safety

Swift has a value type relative to OC. Both Struct and Enum are value types. Defined attributes can be defined as mutable and immutable

  • A lot of people know that a let is thread safe, why is it safe, because it doesn’t change after it’s initialized, it only reads, it doesn’t write, so of course it’s thread safe, so is it thread safe when it’s initialized? The answer is yes, in several cases
  1. If it is a constant defined within a method, it goes without saying that two threads will never initialize the same constant at the same time
  2. If it is a constant property of a class, it is initialized when the class is defined, and object initialization does not occur when two threads simultaneously initialize the same object
  3. In another case, global and static constants are initialized on the first access. To prevent two threads from accessing a constant for the first time, they are initialized in swift_once wrap, as shown by the breakpoint. As for the role of Swift_once, OC developers will know what it is by the name.
  • The Swift standard library uses a large number of value types, and it is recommended that we use value types whenever possible. Value types are explicitly defined to be copied every time they change without affecting the original value, which provides a lot of room for thread-safety
  • Note, however, that this copy process is not thread-safe, and the actual copy will follow COW(copy while writing) to minimize the actual copy
  • So if multiple threads are working on a variable of value type, it’s best not to have this copy process happen in multiple threads, for example
var value: Int = 2
DispatchQueue.global().async {
    print(value)
    value = 3
    print(value)
}
DispatchQueue.global().async {
    print(value)
    value = 4
    print(value)
}
value = 12
print(value)

12 12 12 4 4
12 12 12 3 4
Copy the code

In this case, it must be thread unsafe. One way to avoid Crash is

var value: Int = 2
DispatchQueue.global().async { [value] in
    print(value)
    var value = value
    value = 3
    print(value)
}
DispatchQueue.global().async { [value] in
    print(value)
    var value = value
    value = 4
    print(value)
}
value = 12
print(value)

12 2 2 3 4
Copy the code

The difference is that [value] is explicitly captured when the value is referenced by another thread, which is equivalent to adding a let value = value to the closure. In this case, how does the variable outside the closure change

  • Of course, this example is not practical, in this case because the multithreaded value is not the latest value, the actual development will be treated as the actual situation.