You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/en/posts/post-21/index.md
+12-14Lines changed: 12 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,13 +1,16 @@
1
1
---
2
2
date: 2024-10-16
3
-
title: "Mastering Swift Assertions: Choosing the Right Tool for the Job"
3
+
title: "Swift Assertions Cheatsheet: How, Why, and When to Crash"
4
4
slug: mastering-swift-assertions
5
-
images: [""]
5
+
images: ["https://i.imgflip.com/96ybn9.jpg"]
6
6
description: Should you use assert(), precondition(), or maybe fatalError()? Let's learn how to decide.
7
-
topics: ["Swift"]
7
+
topics: ["Swift", "Cheatsheet"]
8
8
---
9
9
10
-
# Swift Assertions: Choosing the Right Tool for the Job
10
+
# Swift Assertions Cheatsheet: How, Why, and When to Crash
11
+
<center>
12
+
<imgsrc="https://i.imgflip.com/96ybn9.jpg"alt="Chaos Girl Meme: Swift watches while a house labeled `fatalError()` burns.">
13
+
</center>
11
14
12
15
As Swift developers, we have several assertion tools at our disposal. But how do we choose the right one for each situation? This blog post will explore the different types of assertions in Swift and provide a framework to help you decide which to use and when.
13
16
@@ -29,13 +32,6 @@ For this reason, Swift provides us with several tools:
29
32
`assert()` is used to check a condition that must be true for your code to continue execution. If the condition is false, the assertion triggers and the program terminates. But the program will only terminate if this was a debug build. If you build the same code for production then Swift will ignore the `assert()` and move on.
30
33
31
34
```swift
32
-
/// Divides two integers.
33
-
///
34
-
/// - Parameters:
35
-
/// - a: The numerator.
36
-
/// - b: The denominator.
37
-
/// - Returns: The result of the division.
38
-
/// - Precondition: `b` must not be zero.
39
35
funcdivide(_a: Int, byb: Int) ->Int {
40
36
assert(b !=0, "Cannot divide by zero")
41
37
return a / b
@@ -102,7 +98,9 @@ class Animal {
102
98
}
103
99
```
104
100
105
-
Sometimes a class will implement a function with a fatalError if they require subclasses to override it. Another common use case is to fatal error when the app is unable to load the database upon startup. This is a very common pattern when using Core Data for example.
101
+
Sometimes a class will implement a function with a fatalError if they require subclasses to override it. However, I prefer not to use this pattern because it's easy to use this API wrong. For example, in many classes it is expected that you finish an implementation by calling the parent implementation (e.g. `super.makeSound()`). This pattern is used throughout UIKit for example. However, if we called `super.makeSound()` here, it would crash. The fact that it would crash is not obvious at the call site, or the definition. Instead we have to pay close attention to the documentation.
102
+
103
+
Another common use case for `fatalError()` is when the app is unable to load its database upon startup. If the app can't use its database, much if not all of its functionality is broken. It's better to crash. This is a very common pattern when using Core Data for example.
106
104
107
105
## Crashes vs. Errors
108
106
@@ -148,5 +146,5 @@ Today we learned the value of crashing. We also learned how, why and when to cra
148
146
-[Addressing crashes from Swift runtime errors](https://developer.apple.com/documentation/xcode/addressing-crashes-from-swift-runtime-errors)
149
147
-[Analyzing a crash report](https://developer.apple.com/documentation/xcode/analyzing-a-crash-report)
0 commit comments