0
0
Swiftprogramming~20 mins

Weak self and unowned self patterns in Swift - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
Swift Memory Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
What is the output of this Swift closure using weak self?

Consider the following Swift code snippet. What will be printed when start() is called?

Swift
class MyClass {
    var value = 10
    func start() {
        DispatchQueue.global().asyncAfter(deadline: .now() + 1) { [weak self] in
            guard let self = self else {
                print("self is nil")
                return
            }
            print("Value is \(self.value)")
        }
    }
}

var obj: MyClass? = MyClass()
obj?.start()
obj = nil
sleep(2)
ARuntime crash due to unwrapped nil
Bself is nil
CCompilation error due to weak self usage
DValue is 10
Attempts:
2 left
💡 Hint

Think about what happens to obj before the closure runs.

Predict Output
intermediate
2:00remaining
What happens if you use unowned self but self is nil?

What will happen when the following Swift code runs?

Swift
class MyClass {
    var value = 5
    func start() {
        DispatchQueue.global().asyncAfter(deadline: .now() + 1) { [unowned self] in
            print("Value is \(self.value)")
        }
    }
}

var obj: MyClass? = MyClass()
obj?.start()
obj = nil
sleep(2)
ARuntime crash due to accessing deallocated self
BPrints "Value is 0"
CPrints "Value is 5"
DCompilation error due to unowned self usage
Attempts:
2 left
💡 Hint

Consider what happens when self is accessed after being deallocated.

🔧 Debug
advanced
2:00remaining
Identify the cause of a retain cycle in this Swift code

Why does the following Swift code cause a memory leak?

Swift
class ViewController {
    var closure: (() -> Void)?
    func setup() {
        closure = {
            print("Value is \(self)")
        }
    }
}

var vc: ViewController? = ViewController()
vc?.setup()
vc = nil
AClosure is not assigned properly causing nil reference
BClosure captures self weakly causing early deallocation
CClosure captures self strongly causing retain cycle
DNo retain cycle, memory is freed correctly
Attempts:
2 left
💡 Hint

Think about how closures capture variables by default in Swift.

📝 Syntax
advanced
2:00remaining
Which option correctly uses weak self in a closure?

Choose the correct syntax to capture self weakly inside a closure.

Swift
class Example {
    func doWork() {
        DispatchQueue.global().async {
            // capture self weakly here
        }
    }
}
ADispatchQueue.global().async { weak self in print(self?.description) }
BDispatchQueue.global().async { [weak self:] in print(self?.description) }
CDispatchQueue.global().async { [weak self] print(self?.description) }
DDispatchQueue.global().async { [weak self] in print(self?.description) }
Attempts:
2 left
💡 Hint

Remember the syntax for capture lists in Swift closures.

🚀 Application
expert
2:00remaining
How many items are in the dictionary after this Swift code runs?

Consider this Swift code. How many items remain in dict after the code runs?

Swift
class MyObject {}

var dict = [String: MyObject]()

func test() {
    let obj1 = MyObject()
    let obj2 = MyObject()
    dict["one"] = obj1
    dict["two"] = obj2
}

test()
dict.removeValue(forKey: "one")

print(dict.count)
A1
B2
C0
DCompilation error due to weak references
Attempts:
2 left
💡 Hint

Think about how dictionary keys and values behave when you remove an entry.