└── README.md /README.md: -------------------------------------------------------------------------------- 1 | 2 | # iOS Junior Level Interview Questions 3 | ### Download this in PDF format : [Interview Guide e-book](https://github.com/user-attachments/files/18430543/iOS.Developer.Interview.Cheatsheet.1.pdf) 4 | 5 | 6 | > iOS Interview Questions - Your Cheat Sheet For iOS Interview 7 | 8 | ### Prepared by [Shobhakar Tiwari](https://github.com/shobhakartiwari) 9 | ![ïOS MOCK zip - 1](https://github.com/user-attachments/assets/0a35f942-c172-44ce-b7b7-7f07837f4f0c) 10 | 11 | 12 | # Swift Interview Questions 13 | 14 | Welcome to the Swift Interview Questions repository! This document contains a curated list of essential interview questions that can help you prepare for iOS developer roles focusing on Swift programming. Each question is designed to test your knowledge of the Swift language, its features, and best practices. 15 | 16 | ## Questions 17 | 18 | ### 1. What is Swift language? Is it an OOP language or POP (Protocol Oriented Programming)? 19 | *Answer:* Swift is a multi-paradigm programming language that supports both Object-Oriented Programming (OOP) and Protocol-Oriented Programming (POP). 20 | 21 | ### 2. Why is Swift called Protocol Oriented Programming? 22 | *Answer:* Swift emphasizes the use of protocols to define blueprints of methods, properties, and other requirements, promoting a flexible and modular design. 23 | 24 | ### 3. Why is Swift called a strictly type-safe language? 25 | *Answer:* Swift enforces strong type-checking at compile time, reducing runtime crashes and errors by ensuring that variables are used with the correct data types. 26 | 27 | ### 4. What is Optional? 28 | *Answer:* An Optional in Swift is a type that can hold either a value or `nil`, indicating the absence of a value. 29 | 30 | ### 5. Is Optional an ENUM or STRUCT? 31 | *Answer:* Optional is an enumeration (ENUM) that has two cases: `.none` (for `nil`) and `.some(Wrapped)`. 32 | 33 | ### 6. What are the different ways of getting data from optionals? 34 | *Answer:* You can retrieve data from optionals using optional binding (`if let`, `guard let`), forced unwrapping (`!`), or optional chaining. 35 | 36 | ### 7. What are the differences between `guard let` vs `if let`? When would you use `guard let` over `if let`? 37 | *Answer:* `guard let` is used for early exits from a function or loop if the condition is not met, while `if let` allows you to handle the case where an optional contains a value. Use `guard let` for cleaner and more readable code when you need to exit early. 38 | 39 | ### 8. What is the force unwrapping operator and why is it not recommended? 40 | *Answer:* The force unwrapping operator (`!`) is used to retrieve the value of an optional. It is not recommended because if the optional is `nil`, it will cause a runtime crash. 41 | 42 | ### 9. What is a mutable structure? 43 | *Answer:* A mutable structure in Swift is a structure whose properties can be modified after its initial creation. 44 | 45 | ### 10. What is the `mutating` keyword and why is it needed? 46 | *Answer:* The `mutating` keyword is used in methods of structures to indicate that the method can modify the properties of the structure itself. 47 | 48 | ### 11. What is a closure? Is a closure also a function? 49 | *Answer:* A closure is a self-contained block of functionality that can be passed around and used in your code. Yes, closures can be thought of as anonymous functions. 50 | 51 | ### 12. Is closure a reference type or value type? 52 | *Answer:* A closure is a reference type, which means it captures variables and constants from its surrounding context. 53 | 54 | ### 13. Create a function for finding the sum of two numbers and convert this into a sum closure. 55 | ```swift 56 | func sum(a: Int, b: Int) -> Int { 57 | return a + b 58 | } 59 | 60 | let sumClosure: (Int, Int) -> Int = { a, b in 61 | return a + b 62 | } 63 | ``` 64 | 65 | ### 14. Create a structure of an Employee and within this, there should be one Department where the Department has an id and name. 66 | *Answer:* 67 | ```swift 68 | struct Department { 69 | var id: Int 70 | var name: String 71 | } 72 | 73 | struct Employee { 74 | var id: Int 75 | var name: String 76 | var department: Department 77 | } 78 | ``` 79 | 80 | ### 15. What are access modifiers? 81 | *Answer:* Access modifiers define the visibility of properties and methods in Swift, including public, private, fileprivate, and internal. 82 | 83 | ### 16. What is the difference between SceneDelegate and AppDelegate? 84 | *Answer:* AppDelegate manages app-wide behavior, while SceneDelegate manages individual instances of UI. SceneDelegate allows multiple UI scenes to run simultaneously. 85 | 86 | ### 17. What is the use of SceneDelegate? 87 | *Answer:* SceneDelegate is used to manage the lifecycle of a single scene in your app, including its creation and destruction. 88 | 89 | ### 18. What is a Tuple and where should you use it? 90 | *Answer:* A tuple is a group of multiple values that can be of different types. They are useful for returning multiple values from a function. 91 | 92 | ### 19. What are higher-order functions? 93 | *Answer:* Higher-order functions are functions that take other functions as parameters or return functions as their result. 94 | 95 | ### 20. Create an array of strings ["1", "3", "4", "6"] and find the sum of all even numbers using higher-order functions. Don’t use any loops! 96 | *Answer:* 97 | ```swift 98 | let numbers = ["1", "3", "4", "6"] 99 | let evenSum = numbers.compactMap { Int($0) }.filter { $0 % 2 == 0 }.reduce(0, +) 100 | ``` 101 | ### 21. Create an array of Employees and try to filter out those who joined before Jan 2024. 102 | *Answer:* 103 | ```swift 104 | struct Employee { 105 | var name: String 106 | var joiningDate: Date 107 | } 108 | 109 | let employees: [Employee] = [] // Assume this array is populated 110 | let filteredEmployees = employees.filter { $0.joiningDate < Calendar.current.date(from: DateComponents(year: 2024, month: 1, day: 1))! } 111 | ``` 112 | ### 22. What is Responder and what is its use? 113 | *Answer:* The Responder chain is a hierarchy of objects that can respond to events and handle user interactions in iOS. 114 | 115 | ### 23. What are the different options you have to store data locally? 116 | *Answer:* Options for local data storage include UserDefaults, Keychain, Core Data, and file storage. 117 | 118 | ### 24. What is the latest version of Xcode, Swift, iOS, and macOS? 119 | *Answer:* (Provide the current versions at the time of the interview) 120 | 121 | ### 25. Do you know about WWDC? 122 | *Answer:* : Yes, WWDC (Worldwide Developers Conference) is an annual event held by Apple to showcase new software and technologies for developers. 123 | 124 | ### 26. What is iOS and how is it different from other mobile OS? 125 | *Answer:* iOS is Apple's mobile operating system, known for its user-friendly interface, security, and extensive ecosystem. It differs from Android and other OSes in its closed ecosystem and proprietary nature. 126 | 127 | ### 27. If your application is crashing, what are the different ways you can investigate to find out the issue? 128 | *Answer:* Use Xcode debugger, check crash logs, utilize instruments to track memory usage, and analyze code for potential issues. 129 | 130 | ### 28. What is Jailbreak and what is its impact? 131 | *Answer:* Jailbreaking is the process of removing software restrictions on iOS devices, allowing users to install unauthorized apps. It can compromise security and void warranties. 132 | 133 | ### 29. What frameworks are available to create UI in iOS? 134 | *Answer:* Common frameworks include UIKit, SwiftUI, and Interface Builder. 135 | 136 | ### 30. What is the difference between UIKit and SwiftUI? 137 | *Answer:* UIKit is the traditional framework for building iOS apps, while SwiftUI is a newer, declarative framework that allows for faster development and less boilerplate code. 138 | 139 | ### 31. What is an extension? 140 | *Answer:* An extension allows you to add functionality to existing classes, structures, or enumerations without modifying their original implementation. 141 | 142 | ### 32. Use this link: https://hp-api.onrender.com/ to get the data from the server and parse it in a playground to print it. 143 | *Answer:* 144 | ```swift 145 | import Foundation 146 | 147 | let url = URL(string: "https://hp-api.onrender.com/")! 148 | let task = URLSession.shared.dataTask(with: url) { data, response, error in 149 | guard let data = data, error == nil else { return } 150 | // Parse data 151 | } 152 | task.resume() 153 | ``` 154 | 155 | ### 33. What is Keychain? How will you decide whether to save data into Keychain or UserDefaults? 156 | *Answer:* Keychain is a secure storage solution for sensitive data, while UserDefaults is used for storing user preferences. Use Keychain for sensitive information like passwords, and UserDefaults for simple user settings. 157 | 158 | ### 34. What is the problem with global variables? 159 | *Answer:* Global variables can lead to namespace pollution, make code harder to test, and introduce unexpected side effects due to shared state. 160 | 161 | ### 35. What is Property Observer? Write an example. 162 | *Answer:* Property observers allow you to respond to changes in a property’s value. Example: 163 | ```swift 164 | var observedProperty: Int = 0 { 165 | willSet { 166 | print("About to set: \(newValue)") 167 | } 168 | didSet { 169 | print("Just set: \(oldValue) to \(observedProperty)") 170 | } 171 | } 172 | ``` 173 | 174 | ### 36. What is Property Wrapper? Write code to showcase it. 175 | *Answer:* A property wrapper is a custom type that encapsulates the storage and behavior of a property. Example: 176 | ```swift 177 | @propertyWrapper 178 | struct Clamped { 179 | private var value: Value 180 | private let range: ClosedRange 181 | 182 | var wrappedValue: Value { 183 | get { value } 184 | set { value = min(max(newValue, range.lowerBound), range.upperBound) } 185 | } 186 | 187 | init(wrappedValue: Value, _ range: ClosedRange) { 188 | self 189 | ``` 190 | ### 37. Question: What sorting algorithm does the sorted() function in Swift use, and what is its time complexity in the average and worst-case scenarios? 191 | *Answer:* 192 | The sorted() function in Swift uses the Timsort algorithm, which is a hybrid sorting algorithm derived from merge sort and insertion sort. Its time complexity is as follows: 193 | 194 | Average Case: O(n log n) 195 | Worst Case: O(n log n) 196 | Timsort is designed to perform well on many kinds of real-world data and is particularly efficient for data that is already partially sorted. 197 | 198 | ### 38. Question: Given the following code snippets, which approach is safer for ensuring main-thread execution, and why? 199 | ```swift 200 | // Approach 1 201 | DispatchQueue.main.async { 202 | // UI update code 203 | } 204 | 205 | // Approach 2 206 | DispatchQueue.main.sync { 207 | // UI update code 208 | } 209 | ``` 210 | *Answer:* 211 | - Approach 1 (DispatchQueue.main.async) is generally safer for ensuring main-thread execution, especially when called from a background thread. Using async avoids potential deadlocks, as it schedules the task to run on the main thread without blocking the calling thread. 212 | 213 | - n Approach 2, where DispatchQueue.main.sync is used, you’re telling the main thread: "Wait until this code is finished before moving on." This can be risky if you're already on the main thread, because the main thread is already busy running whatever code you just told it to wait on. Since it can’t move on until that code is done, and the code can't start because the main thread is waiting, both get stuck waiting for each other. This creates a deadlock, where nothing can proceed. 214 | 215 | ### 39. Question: How would you ensure that a background task runs asynchronously while avoiding any blocking on the main thread? 216 | *Answer:* 217 | - Use DispatchQueue.global().async to run tasks on a background thread asynchronously. This prevents any blocking on the main thread, allowing UI updates or user interactions to remain responsive. 218 | 219 | ### 40. Question: Question: What’s the difference between DispatchQueue.main.async and DispatchQueue.global().async when updating UI elements? 220 | *Answer:* 221 | - DispatchQueue.main.async ensures code runs on the main thread, which is necessary for UI updates in iOS. DispatchQueue.global().async runs code on a background thread, which is ideal for tasks that don't involve UI changes or don’t require main-thread access, such as data processing or network requests. 222 | 223 | ### 40. Question: When should you prefer DispatchQueue.main.async over DispatchQueue.main.sync? 224 | *Answer:* 225 | - you should generally prefer DispatchQueue.main.async when updating the UI or performing tasks on the main thread from a background thread. Using async avoids potential deadlocks and doesn’t block the calling thread, ensuring smoother and safer execution on the main thread. sync is rarely used in this context as it can lead to deadlocks if misused. 226 | 227 | ### 41. Question: Explain a scenario where using DispatchQueue.global().asyncAfter might be helpful, and describe how it works. 228 | *Answer:* 229 | - DispatchQueue.global().asyncAfter is useful for delaying the execution of background tasks. For example, it might be used to implement a delay before retrying a failed network request. This method schedules code to run on a background queue after a specified delay without blocking the main thread, ensuring a responsive user interface. 230 | 231 | ### 42. In what scenario would DispatchQueue.main.sync be useful, and why is it generally avoided? 232 | *Answer:* 233 | - DispatchQueue.main.sync is rarely used in iOS development because it can easily lead to deadlock if called from the main thread. However, there are limited cases where it can be useful—typically, when you need to perform a task on the main thread immediately and you’re calling it from a background thread. 234 | - For example, if you’re performing some heavy data processing in the background and need to update a critical UI element synchronously (such as disabling a button or updating a label instantly), DispatchQueue.main.sync ensures that the UI update happens right away. However, this should be used with caution and only from a background thread. 235 | ```swift 236 | DispatchQueue.global().async { 237 | // Heavy data processing on a background thread 238 | let result = processData() 239 | 240 | // Synchronously updating a critical UI element on the main thread 241 | DispatchQueue.main.sync { 242 | self.resultLabel.text = "Result: \(result)" 243 | self.updateButton.isEnabled = false 244 | } 245 | } 246 | ``` 247 | 248 | ### 43. What is a non-escaping closure, and when would you typically use one in Swift? 249 | *Answer:* 250 | - A non-escaping closure is a closure that is guaranteed to be executed before the function it’s passed to returns. This means the closure does not “escape” or outlive the scope of the function. Non-escaping closures are the default in Swift. 251 | 252 | - You typically use non-escaping closures when you need a closure to perform some work within the function itself and don’t need to store it to be used later. For example, you’d use a non-escaping closure for simple data processing tasks where the closure’s work can be completed within the function’s scope. 253 | ```swift 254 | func performTask(_ task: () -> Void) { 255 | print("Start Task") 256 | task() // The closure is executed within the function scope 257 | print("End Task") 258 | } 259 | 260 | performTask { 261 | print("Performing task") 262 | } 263 | ``` 264 | 265 | ### 44. Why is it safer to use non-escaping closures when you don’t need the closure to persist outside the function? 266 | *Answer:* 267 | - Non-escaping closures are safer because they avoid potential memory management issues, like retain cycles. Since they do not outlive the function, the function controls the closure’s lifecycle, making memory management straightforward. By default, Swift treats closures as non-escaping, which helps prevent memory leaks unless explicitly specified. 268 | 269 | ### 45. Give an example of when using an escaping closure is required instead of a non-escaping closure. 270 | *Answer:* 271 | - An escaping closure is required when you need to call the closure after the function has returned, such as in asynchronous operations. 272 | - For instance, if you are fetching data from a server, the network request runs asynchronously, so the closure must “escape” to be called once the request is complete: 273 | ```swift 274 | func fetchDataFromServer(completion: @escaping (Data?) -> Void) { 275 | DispatchQueue.global().async { 276 | // Simulate a network delay 277 | let data: Data? = Data() // Simulated data 278 | completion(data) // Called after function returns 279 | } 280 | } 281 | ``` 282 | 283 | ### 46. What are the different quality of service (QoS) classes in GCD, and which has the highest priority? 284 | *Answer:* 285 | - GCD defines several quality of service (QoS) classes to prioritize tasks based on their urgency and intended purpose. The classes are: 286 | - User-interactive – Highest priority 287 | - User-initiated 288 | - Default 289 | - Utility 290 | - Background – Lowest priority 291 | - The User-interactive class has the highest priority. It is used for tasks that need to update the UI immediately, such as responding to user actions. - - - - Conversely, the Background class has the lowest priority and is intended for tasks that are not time-sensitive, like pre-fetching data or syncing in the background. 292 | 293 | ### 47. When would you use the User-initiated QoS in GCD? 294 | *Answer:* 295 | - The User-initiated QoS class is used for tasks that the user expects to complete as part of their current interaction but are not necessarily required for immediate UI updates. It is useful for tasks that are started by a user action and should finish as soon as possible to provide a smooth user experience. 296 | - For example, if a user selects an item to view details that require data loading, you would use the User-initiated QoS to load the data in the background, ensuring it completes promptly without blocking the main thread. 297 | ```swift 298 | DispatchQueue.global(qos: .userInitiated).async { 299 | // Fetch data needed for displaying item details 300 | let data = fetchData() 301 | DispatchQueue.main.async { 302 | // Update UI with data 303 | self.updateUI(with: data) 304 | } 305 | } 306 | ``` 307 | ### 48. What is the Utility QoS, and when should it be used? 308 | *Answer:* 309 | - The Utility QoS class is used for tasks that the user is aware of but doesn’t need immediately. This priority level is appropriate for tasks that involve long-running work, such as downloading files or processing data in the background. Tasks with this priority consume fewer system resources, preserving battery life and performance for higher-priority tasks. 310 | ```swift 311 | DispatchQueue.global(qos: .utility).async { 312 | // Long-running task, such as downloading a large file 313 | let fileData = downloadLargeFile() 314 | DispatchQueue.main.async { 315 | // Update UI with completion status 316 | self.showDownloadComplete() 317 | } 318 | } 319 | ``` 320 | ### 49 .How does the Background QoS class differ from the Utility QoS class? 321 | *Answer:* 322 | - The Background QoS class is even lower in priority than Utility and is used for tasks that the user doesn’t need to be aware of, such as prefetching data, indexing, or syncing. Background tasks are intended to run with minimal impact on system performance and battery life. 323 | 324 | - Use Background QoS for work that can happen “behind the scenes” without the user noticing, like updating caches or synchronizing with a server. 325 | 326 | ### 50. Which GCD QoS class would you use for tasks that must respond to user actions in real-time, and why? 327 | - Answer: For tasks that need to respond to user actions in real-time, you should use the User-interactive QoS class. This is the highest-priority class, ensuring tasks are performed immediately, typically on the main thread, for an instantaneous response to user interactions, such as animations or touch responses. 328 | ```swift 329 | DispatchQueue.global(qos: .userInteractive).async { 330 | // Immediate response task, such as a small animation or UI update 331 | performQuickTask() 332 | } 333 | ``` 334 | ### 50 . GCD QoS Classes with Priorities: 335 | - User-interactive – Immediate, time-sensitive tasks (highest priority). 336 | - User-initiated – Tasks initiated by the user that should finish quickly. 337 | - Default – The standard priority for tasks without a specified priority. 338 | - Utility – Long-running tasks that do not need immediate attention. 339 | - Background – Low-priority tasks that run behind the scenes (lowest priority). 340 | 341 | ### 51. Why Weak is slower than Strong ? 342 | - refer to my medium article for this : https://medium.com/@shobhakartiwari/why-weak-is-slower-than-strong-e6c805784ed8 343 | 344 | ### 52. What is the difference between “immutable” and “mutable” objects in Swift? 345 | - refer to my medium article for this : https://medium.com/@shobhakartiwari/immutable-vs-mutable-objects-in-swift-an-ios-developers-perspective-fae2763be87f 346 | 347 | # Swift Testing Interview Questions and Answers 348 | 349 | ### **53: What is unit testing, and why is it important?** 350 | **A:** Unit testing is a software testing method where individual components or functions are tested in isolation. It ensures code correctness, simplifies debugging, and enhances code quality. 351 | 352 | ### **:54 How do you set up a unit test target in Xcode?** 353 | **A:** 354 | 1. Open your Xcode project. 355 | 2. Select **File > New > Target**. 356 | 3. Choose **Unit Testing Bundle**. 357 | 4. Name the target and click **Finish**. 358 | 359 | ### **55: What is XCTest?** 360 | **A:** XCTest is Apple's testing framework used for writing unit tests and UI tests for iOS, macOS, watchOS, and tvOS applications. 361 | 362 | ### **56: How do you create a test case class using XCTest?** 363 | ```swift 364 | import XCTest 365 | 366 | class MyTests: XCTestCase { 367 | func testExample() { 368 | let result = 2 + 2 369 | XCTAssertEqual(result, 4, "The result should be 4") 370 | } 371 | } 372 | ``` 373 | 374 | ### **56: Explain the lifecycle of a test method in XCTest.** 375 | **A:** XCTest provides the following lifecycle methods: 376 | - `setUp()`: Called before each test method. 377 | - `tearDown()`: Called after each test method. 378 | - `setUpWithError()` & `tearDownWithError()`: Handle throwing errors if needed. 379 | 380 | ### **57: What are assertions in unit testing? Provide examples.** 381 | **A:** Assertions check test expectations. Common assertions: 382 | ```swift 383 | XCTAssert(true) // General assertion 384 | XCTAssertEqual(2 + 2, 4) // Equality check 385 | XCTAssertNotEqual(2 + 2, 5) // Inequality check 386 | XCTAssertNil(nil) // Nil check 387 | XCTAssertNotNil("Hello") // Non-nil check 388 | ``` 389 | 390 | ### **58: How do you write asynchronous test cases using XCTest?** 391 | ```swift 392 | func testAsyncCall() { 393 | let expectation = self.expectation(description: "Async Call") 394 | 395 | fetchData { data in 396 | XCTAssertNotNil(data) 397 | expectation.fulfill() 398 | } 399 | 400 | waitForExpectations(timeout: 5, handler: nil) 401 | } 402 | ``` 403 | 404 | ### **59: What are test doubles? Explain mocks, stubs, and fakes.** 405 | **A:** 406 | - **Mocks:** Objects that verify interactions. 407 | - **Stubs:** Provide predefined responses. 408 | - **Fakes:** Provide working implementations, usually for testing only. 409 | 410 | ### **60: How would you mock a network call in a unit test?** 411 | ```swift 412 | class MockNetworkService: NetworkService { 413 | func fetchData(completion: @escaping (Data?) -> Void) { 414 | let mockData = Data([0x0, 0x1, 0x2]) 415 | completion(mockData) 416 | } 417 | } 418 | ``` 419 | 420 | ### **61: What is TDD, and what are its benefits?** 421 | **A:** TDD involves writing tests before writing the actual implementation code. Benefits include: 422 | - Reduces bugs. 423 | - Improves design. 424 | - Provides better test coverage. 425 | 426 | ### **62: How would you follow TDD in Swift?** 427 | 1. Write a failing test. 428 | 2. Implement the code to pass the test. 429 | 3. Refactor the code. 430 | 431 | Example: 432 | ```swift 433 | class CalculatorTests: XCTestCase { 434 | func testAddition() { 435 | let result = Calculator.add(2, 3) 436 | XCTAssertEqual(result, 5) 437 | } 438 | } 439 | 440 | struct Calculator { 441 | static func add(_ a: Int, _ b: Int) -> Int { 442 | return a + b 443 | } 444 | } 445 | ``` 446 | 447 | --- 448 | 449 | ### **63: What is code coverage, and how do you enable it in Xcode?** 450 | **A:** Code coverage measures how much of the source code is tested by unit tests. 451 | 452 | To enable it: 453 | 1. Open Xcode. 454 | 2. Go to **Product > Scheme > Edit Scheme...** 455 | 3. Select **Test** and check **Gather Coverage for Targets**. 456 | 457 | ### **64: How do you interpret code coverage reports?** 458 | **A:** Xcode's code coverage tool highlights lines of code that are tested. Green means fully tested, while red indicates untested code. 459 | 460 | ### **64: What are best practices for writing unit tests?** 461 | - Write independent tests. 462 | - Use meaningful test method names. 463 | - Test one thing per method. 464 | - Use test doubles when needed. 465 | - Keep tests readable and maintainable. 466 | 467 | ### **65: How can you prevent unreliable tests from occurring?** 468 | - Avoid external dependencies. 469 | - Use mock services. 470 | - Ensure consistent test data. 471 | 472 | ### **66: How do you test Core Data models in unit tests?** 473 | ```swift 474 | func testCoreDataModel() { 475 | let context = PersistenceController.shared.container.viewContext 476 | let entity = MyEntity(context: context) 477 | entity.name = "Test" 478 | 479 | do { 480 | try context.save() 481 | XCTAssertNotNil(entity) 482 | } catch { 483 | XCTFail("Saving failed") 484 | } 485 | } 486 | ``` 487 | 488 | ### **67: How do you test view models in MVVM architecture?** 489 | ```swift 490 | class ViewModelTests: XCTestCase { 491 | func testViewModelFetch() { 492 | let viewModel = MyViewModel(service: MockService()) 493 | viewModel.fetchData() 494 | XCTAssertEqual(viewModel.data.count, 3) 495 | } 496 | } 497 | ``` 498 | ### **68. When you should use strong, weak and unowned?** 499 | - When working with reference types in Swift, managing memory is crucial to avoid retain cycles. Here's a quick guide to determine when to use 𝗌𝗍𝗋𝗈𝗇𝗀, 𝗐𝖾𝖺𝗄, or 𝗎𝗇𝗈𝗐𝗇𝖾𝖽 references: 500 | 501 | 👉 𝗦𝘁𝗿𝗼𝗻𝗴 – Best for hierarchical relationships (e.g., parent owns child). 502 | 👉 𝗪𝗲𝗮𝗸 – Use when instances are optionally related to each other. 503 | 👉 𝗨𝗻𝗼𝘄𝗻𝗲𝗱 – Use when one instance cannot exist without the other (mandatory dependency). 504 | Screenshot 2024-12-23 at 12 21 59 AM 505 | 506 | 507 | ### **69. Why stored property not allowed within Enum ? 508 | - Follow this link for answer : https://medium.com/@shobhakartiwari/why-are-stored-properties-not-allowed-in-enums-in-swift-31c27f0210ca 509 | --------------------------------------------------------------------------------