iOS Interview Questions: Swift

Updated Sep 11, 2022iosswiftinterviewquestions

Preparing for an iOS interview requires you to take considerable amount of time to review Swift language features. Try to skim as many following questions as possible, you might not remember every possible question but at least heard about it.

1. Why is Swift a type-safe language?

Swift encourages you to be clear about the types of values your code can work with. It performs type checks when compiling your code and flags any mismatched types as errors. This enables you to catch and fix errors as early as possible in the development process.

2. What are optionals in Swift?

An optional represents two possibilities: Either there is a value, and you can unwrap the optional to access that value, or there isn’t a value at all.

The concept of optionals doesn’t exist in C or Objective-C. The nearest thing in Objective-C is the ability to return nil from a method that would otherwise return an object, with nil meaning “the absence of a valid object.”

Swift’s optionals let you indicate the absence of a value for any type at all, without the need for special constants.

3. What is the difference between assertions and preconditions?

Assertions and preconditions are checks that happen at runtime. You use them to make sure an essential condition is satisfied before executing any further code.

The difference between assertions and preconditions is in when they’re checked: Assertions are checked only in debug builds, but preconditions are checked in both debug and production builds. In production builds, the condition inside an assertion isn’t evaluated. This means you can use as many assertions as you want during your development process, without impacting performance in production.

4. Why immutability is important in Swift?

Immutability helps safety and performance. Immutable objects are useful in multi-threaded applications because multiple threads can act on the data of immutable objects without worrying about changes to the data by other threads.

As immutable objects are closed to change, it is safe to assume that they will stay unchanged while we access the object from different threads. This assumption simplifies most of the multithreading problems that are complex to solve and maintain. For instance, we do not need to think about synchronization/locking mechanisms at all.

5. Why were C-style for-loops removed in Swift 3?

The C-style for-loop appears to be a mechanical carry-over from C rather than a genuinely Swift-specific construct. It is rarely used and not very Swift-like.

More Swift-typical construction is already available with for-in statements and stride. Removing for loops would simplify the language and starve the most common use-points for -- and ++, which are already due to be eliminated from the language.

6. What are types of closures?

Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages.

Closures can capture and store references to any constants and variables from the context in which they’re defined. Closures take one of three forms:

  • Global functions are closures that have a name and don’t capture any values.
  • Nested functions are closures that have a name and can capture values from their enclosing function.
  • Closure expressions are unnamed closures written in a lightweight syntax that can capture values from their surrounding context.

7. What is the difference between structures and classes?

Structures and classes are general-purpose, flexible constructs that have many things in common.

  • Define properties to store values.
  • Define methods to provide functionality.
  • Define subscripts to provide access to their values using subscript syntax.
  • Define initializers to set up their initial state.
  • Be extended to expand their functionality beyond a default implementation.
  • Conform to protocols to provide standard functionality of a certain kind.

Classes have additional capabilities that structures don’t have:

  • Inheritance enables one class to inherit the characteristics of another.
  • Type casting enables you to check and interpret the type of a class instance at runtime.
  • Deinitializers enable an instance of a class to free up any resources it has assigned.
  • Reference counting allows more than one reference to a class instance.

8. How to choose between value types and reference types?

The most basic distinguishing feature of a value type is that copying — the effect of assignment, initialization, and argument passing — creates an independent instance with its own unique copy of its data.

Copying a reference, on the other hand, implicitly creates a shared instance. After a copy, two variables then refer to a single instance of the data, so modifying data in the second variable also affects the original.

One of the primary reasons to choose value types over reference types is the ability to more easily reason about your code. Importantly, you can safely pass copies of values across threads without synchronization.

When you’re working with Cocoa, many APIs expect subclasses of NSObject, so you have to use a class. For the other cases, here are some guidelines:

Use a value type when:

  • Comparing instance data with == makes sense
  • You want copies to have independent state
  • The data will be used in code across multiple threads

Use a reference type (e.g. use a class) when:

  • Comparing instance identity with === makes sense
  • You want to create shared, mutable state