Swift interview questions and answers 👇

  1. Swift Interview Questions


Swift Interview Questions

1.

What’s the difference between == and ===?

== operator checks if the values are the same, comparing value types. "equal to" === operator checks if the references point the same instance (both point to the same memory address), comparing reference types. "identical to"

2.

What is the difference between fileprivate, private and public private(set) access level ?

fileprivate is accessible within the current file. private is accessible within the current class. public private(set) means getter is public, but the setter is private.

3.

What is the difference between Delegates and Callbacks ?

Delegation simply means that you pass yourself to someone else, when you want that someone to notify you of changes, so you can react to them. For instance, if a ViewController talks to a network service, and wants to get notified when that service is done with some request, it would make itself the network service’s delegate. The network service would then call the delegate methods when it’s done.

Callbacks are similar in function to the delegate pattern. They do the same thing: letting other objects know when something happened, and passing data around. What differentiates them from the delegate pattern, is that instead of passing a reference to yourself, you are passing a function.

4.

What is copy or write?

Copy-on-write is a strategy used in Swift for optimising memory usage. The main idea of COW is that when multiple callers want to access the resources which are same, you can put them pointing to the same resource. The state of the resource will be maintained until a caller tries to modify its “copy” of the resource.

5.

Rewrite this code in a Swift way

Problem

Consider:

let list = [Int](1...5)
var arrayOfTuples = [(Int, Int)]()

for (index, element) in list.enumerated() {
    arrayOfTuples += [(index, element)]
}

print(arrayOfTuples) // prints [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]

Can you rewrite this code in a more "swiftier" way?

Answer Yeap, the way to do it is:

let list = [Int](1...5)
let arrayOfTuples = Array(list.enumerated())
print(arrayOfTuples) // prints [(offset: 0, element: 1), (offset: 1, element: 2), (offset: 2, element: 3), (offset: 3, element: 4), (offset: 4, element: 5)]

or with map:

let list = [Int](1...5)
let arrayOfDictionaries = list.enumerated().map { (a, b) in return [a : b] }
print(arrayOfDictionaries) // prints [[0: 1], [1: 2], [2: 3], [3: 4], [4: 5]]
6.

What is trailing closure syntax?

Many functions in iOS accept multiple parameters where the final parameter is a closure. Trailing closure syntax is a little piece of syntactic sugar that makes particularly common code more pleasant to read and write.

Consider:

func greetThenRunClosure(name: String, closure: () -> ()) {
    print("Hello, \(name)!")
    closure()
}
Use:

greetThenRunClosure(name: "Paul") {
    print("The closure was run")
}

This functionality is available wherever a closure is the final parameter to a function.

7.

8.

What is Dictionary in Swift?

It enables you to store the key-value pairs and access the value by providing the key. It is similar to that of the hash tables in other programming languages.

9.

How can you make a property optional in Swift?

An optional in Swift is a type that can hold either a value or no value. Optionals are written by appending a ? to any type:

Example

var name: String? = "Online Interview Questions" Declaring a question mark "?" in the code can make a property optional. If a property doesn’t hold a value, then this symbol "?" helps in avoiding the runtime errors.

10.

Explain Functions in Swift Programming?

Functions let you group a series code altogether to perform a specific task. A function is written once and called any number of time in the code.

In swift programming, func keyword is used to create a function

func greet(person: String) -> String {
    let greeting = "Hello, " + person + "!"
    return greeting
}
11.

How can you define a base class in swift?

The classes are not inherited directly from the base class in the Swift programming language.The classes defined by the developer without specifying the superclass becomes the base class automatically.

12.

What are the control transfer statements in swift?

The control transfer statements in swift are: Continue Break Fallthrough Return

13.

What do you mean by the term “defer”?

The term “defer” is a keyword that provides a block of code that executes when the execution is leaving the current scope.

14.

Can you explain any three-shift pattern matching techniques?

  • Typecasting Patterns – This pattern allows you to match or cast the types.
  • Wildcard Patterns – This pattern matches as well as ignores any kind and type of value.
  • Optional Patterns – This pattern is used to match the optional values.
15.

Explain the difference between let and var in Swift Programming?

Both the terms 'let' and 'var' are used for declaring the functions in JavaScript but the main difference between these two terms is that the 'let' is block scoped while a 'var' is the functional scope. It is not wrong to say that a variable represented with var is defined throughout the program in relation to let

Example of var:

Input: 
console.log(x); 
var x=5; 
console.log(x); 
Output: undefined 5
Example of let:

Input: 
console.log(x); 
let x=5; console.l
og(x); 
Output: Error
16.

What is difference between single and double ? in Swift?

Single ? in Swift is used to denote an optional value either contains a value or contains nil to indicate that the value is missing.

double ?? in swift is called nil coalescing operator that finds if optional has no value then it uses a default value.

17.

List some control transfer statements used in Swift?

Some control statements are:

  • Control flow statements as the name suggests are efficient to check the course of execution in a program. There are several kinds of control transfer statements are present in Swift such as loop branch statement, loop statement, and control transfer statement
  • Loop branch permit a block of code to be executed time and again
  • Branch statements permit a particular block of code to be executed only if some circumstances are satisfied,
  • Control transfer statements present a method to change the system in which code is executed.
18.

Explain Deinitializer in Swift programming Language?

In Swift, a deinitializer is used to free up the resources by deallocates your instance class when they remain no longer useful for you. a dinit keyword is used to represent it. It is only present on class types.

19.

What is the difference between nil and None in Swift?

Usually, there is no difference between nil and None in Swift. nil & .none are the equivalent to each other.

20.

What are generics? How to make a method or variable generics in Swift?

Generic is efficient to write sensitive and reusable functions and types. It is provided in Swift 4. Most of the people use this feature to evade the risk of duplication. 'Arrays' and 'Dictionary' are also referred to generic collection. The libraries of Swift 4 are comprised of generic code.

You can add generics to a method (function) but can’t add to a variable. Understand it with an example:

func Vector3D(x: [T], y: [T], z: [T])
 {    self.xCord = x
    self.yCord = y
    self.zCord = z}

In this example, the generic created here is in a function. You can change the T with anything you want. This is how you can add generic in function.

21.

How to call Objective-C code from Swift

Follow the following steps:

Step 1: Add Objective-C Implementation --.m: First of all, add a .m file to the class and then name it CustomObject.m.

Step 2: Add Bridging Header: At the time of adding your .m file, you receive a prompt with three options of YES, NO and cancel. You need to select YES

Step 3: Add Objective-C Header --.h: After that Add one more .h file and name it CustomObject.h.

Step 4: Build your Objective-C Class

In CustomObject.h

#import <Foundation/Foundation.h>
@interface CustomObject : NSObject
@property (strong, nonatomic) id someProperty;
- (void) someMethod;
@end
In CustomObject.m
#import "CustomObject.h"
@implementation CustomObject 
- (void) someMethod {
    NSLog(@"SomeMethod Ran");
}
@end

Step 5: The next step is to add Class to Bridging-Header

In YourProject-Bridging-Header.h

#import "CustomObject.h"

Step 6: At last, use your Object

In SomeSwiftFile.swift:

     var instanceOfCustomObject: CustomObject = CustomObject()
     instanceOfCustomObject.someProperty = "Hello World"
     println(instanceOfCustomObject.someProperty)
    instanceOfCustomObject.someMethod()

In the bridging header, there is no need to import explicitly

22.

How to create a constant in Swift Programming?

You have to use the let keyword to declare a constant in Swift Programming. Here is the example in which we show you how to use declare street as a constant in lieu of a variable. But for this, you need to use let keyword.

let street: String = "5th Avenue"
var number: Int
street = "Main Street"
number = 10

Swift does not allow you to change the value of constant. If you want to update the first line then XCode will show an error for a naive reason. Comment out or remove the line in which you want to change the value to the street so that it won't create any type of error.

let street: String = "5th Avenue"
var number: Int
// street = "Main Street"
number = 10
23.

In Swift What is use of backticks ` while declaring a variable?

Backticks (`) are used as a name and to surround the keyword in the case if you want to give the same name as a reserved Swift keyword to a constant or a variable. But it is strongly advised to ignore the keyword unless you have no choice available.

24.

How to declare an empty dictionary in Swift?

We can declare an empty dictionary in swift by identify clearly the

 key:value 
Data type inside square brackets [ ].

Example
let emptyDic:Dictionary<Int, String> = [:]
print(emptyDic)
25.

In Swift, what type of object are basic data types?

Swift utilizes the standard set of basic data types for different purposes such as numbers, Boolean values, and strings.

1.Int: Int is used to store the integer value. On 32-bit devices, it is always 32 bits deep and on 64-bit devices, it has 64 bits deep. You are able to access the maximum and minimum values the type enable store with the help of the min and max static properties:

println("\(Int.min)")
//output on 32-bit device: -2147483648
//output on 64-bit device: -9223372036854775808
println("\(Int.max)")
//output on 32-bit device: 2147483647
//output on a 64-bit device: 9223372036854775807
  1. Double and Float: The use of Float and Double in Swift is considered when you are used to working with the decimal number. Double will be always 64-bit whereas float is always a 32- bit value. It does not depend upon the architecture of the device. The compiler utilizes the Double type instead of a Float in case of using decimal literal values. So, if you don't need the value of a 64-bit value, then it is definitely that you declare

Float variable. var distance = 0.0 //distance is a Double var seconds: Float = 0.0 // second is a Float

  1. Bool: The Bool basic type is used to store the Boolean value. The main difference between the Objective-C and Swift is it uses true and false instead of YES and NO as in Objective-C

It is unable to compare the value to 0 or nil in Swift. The expression that can definitely retort a Bool cam come into used to describe a boot value. Let's take an example

var someInteger = 0
var hasSome:Bool = (someInteger != 0)
//hasSome: false
someInteger = 100
hasSome = (someInteger != 0)
//hasSome = true
  1. Strings: String literals are the text that is enclosed by double quotes in Swift. var greetingString = "I am Rich"

A string is the factory of the characters and the character pictures a Unicode character, has symbols, one of more than 100 scripts and 110,000 characters. There are a large number of character encoding method to implement the characters like UTF-8 or UTF-16. These encoding methods store every character with the help of a variable number of bytes in memory.

  1. Arrays: In Swift, arrays are the collection types. It is an arranged list of the items of the equal type. At the time of declaring an array in Swift, you need to specify what type it will contain. When it is done, it is able to contain only that type. This whole process is to help you in ensuring the expected guaranteed type when you pull an item out of the array. You enclosed a list of elements with square brackets to create an array literal. For example var dogs = ["Harlow", "Cliff", "Rusty", "Mia", "Bailey"]

You need to assure that all the should be of equal types or else you will get a compile-time error.

It consists of two ways to represent that is long form and short form. Both the ways are comparable can be used mutually

Long form: Array Short form: [ValueType]

  1. Dictionaries: A dictionary is an unordered factory of items of a particular type and every type is connected with a unique key. Like the arrays, it also contains the two ways to represent the type: the short form and the long form. Both of these types are comparable and can be used mutually.

Long form: Dictionary<KeyType, ValueType> Short form: [KeyType: ValueType] Here is an example of syntax to declare and initialize a dictionary with the use of short form.

var people: [String:SomePersonClass] = [:] //explicit type

//or, alternately

var people = String:SomePersonClass //implicit type

26.

What are initializer in Swift?

Swift initializer is a special type of method that can be called to create a new instance of a particular type.

Swift provides a default initializer for any structure or class that provides default values for all of its non-optional properties and does not provide the initializer itself.

Swift initializer Example

class User {
    var first_name: String
    var last_name: String
    
    init(first_name: String, last_name: String) {
        self.first_name = first_name
        self.last_name = last_name
    }
}
let p = Person(first_name:"Santosh", last_name:"Botre")
27.

What is forced unwrapping? Why is it potentially unsafe?

Force unwrapping in swift is a process of converting an optional type to a non-optional type.

Force unwrapping is potentially unsafe because if the optional has no value and you try to unwrap it, this will trigger a runtime error and cause the app to crash

28.

What is an in-out parameter in Swift?

In-out parameter lets you change the value of a function parameter from within the body of that function.

29.

What is an attribute in Swift?

In Swift, an attribute is a construct which provides some additional information of declaration or its type. It is represented with @ symbol and then succeeded by the attribute name and arguments. Arguments are distinct only to some attributes. For example,

@available(<attribute_name>)

@available(<attribute_name>)(<arguments>)

@available
30.

Explain What is half-open range operator?

It is an operator (a<b) that is used to defines a range that runs from a to b but it doesn’t contain b. The reason for its name that is half-open is that it does not contains its last value, just have its first value. The value of 'a' compulsory is not greater than b in the closed ranged operator. The resulting range will be empty in the case of a is equal to b.

It is useful when you are working with zero-based lists like arrays where it is useful to calculate the length of the list. For example:

let names = ["Alley", "Anna", "Jack", "Brian"]
let count = names.count
for i in 0..<count span id="docs-internal-guid-b356581b-7fff-3109-a868-e60b14559aae">count
print("Person \(i + 1) is called \(names[i])")
} // Person 1 is called Alley, Person 2 is called Anna,
31.

What is tuple? How to create a tuple in Swift ?

A tuple is used to arrange multiple values in a single compound Value. In tuple, it is not compulsory for value to be of the same type. It can be of any type.

For an instance, ("interview", 123) is a tuple having two values: one is string Type, and another one is an integer type.

To create a tuple: To create it, you should have tuple literals which are a list of values listed in tuple separated by the comma. For example, the point is a tuple created by tuple literals written in between a pair of parentheses. To change a tuple literal, use dot notation with tuple’s name and assign the desired value. Check example:

var point = (0, 0)
point.0 = 10
point.1 = 15
point // (10, 15)
32.

What are the values of tutorial1.difficulty and tutorial2.difficulty? Would this be any different if Tutorial was a class? Why or why not?

Consider the following:

struct Tutorial {
  var difficulty: Int = 1
}

var tutorial1 = Tutorial()
var tutorial2 = tutorial1
tutorial2.difficulty = 2

What are the values of tutorial1.difficulty and tutorial2.difficulty? Would this be any different if Tutorial was a class? Why or why not?

tutorial1.difficulty is 1, whereas tutorial2.difficulty is 2.

Structures in Swift are value types. You copy value types by value rather than reference. The following code creates a copy of tutorial1 and assigns it to tutorial2:

var tutorial2 = tutorial1

A change to tutorial2 is not reflected in tutorial1.

If Tutorial were a class, both tutorial1.difficulty and tutorial2.difficulty would be 2. Classes in Swift are reference types. When you change a property of tutorial1, you’ll see it reflected in tutorial2 and vice versa.

33.

You’ve declared view1 with var, and you’ve declared view2 with let. What’s the difference, and will the last line compile?

import UIKit

var view1 = UIView()
view1.alpha = 0.5

let view2 = UIView()
view2.alpha = 0.5 // Will this line compile?

Yes, the last line will compile. view1 is a variable, and you can reassign it to a new instance of UIView. With let, you can assign a value only once, so the following code would not compile:

view2 = view1 // Error: view2 is immutable

However, UIView is a class with reference semantics, so you can mutate the properties of view2 — which means that the last line will compile:

let view2 = UIView()
view2.alpha = 0.5 // Yes!
34.

This complicated code sorts an array of names alphabetically. Simplify the closure as much as you can.

var animals = ["fish", "cat", "chicken", "dog"]
animals.sort { (one: String, two: String) -> Bool in
    return one < two
}
print(animals)

The type inference system automatically calculates both the type of the parameters in the closure and the return type, so you can get rid of them:

animals.sort { (one, two) in return one < two }

You can substitute the $i notation for the parameter names:

animals.sort { return $0 < $1 }

In single statement closures, you can omit the return keyword. The value of the last statement becomes the return value of the closure:

animals.sort { $0 < $1 }

Finally, since Swift knows that the elements of the array conform to Equatable, you can simply write:

animals.sort(by: <)

35.

What is an optional and which problem do optionals solve?

An optional lets a variable of any type represent a lack of value. In Objective-C, the absence of value is available only in reference types using the nil special value. Value types, such as int or float, do not have this ability.

Swift extends the lack of value concept to both reference and value types with optionals. An optional variable can hold either a value or nil, indicating a lack of value.

36.

Summarize the main differences between a structure and a class.

You can summarize the differences as:

Classes support inheritance; structures don't. Classes are reference types; structures are value types.

37.

What are generics and which problem do they solve?

In Swift, you can use generics in both functions and data types, e.g. in classes, structures or enumerations.

Generics solve the problem of code duplication. When you have a method that takes one type of parameter, it's common to duplicate it to accommodate a parameter of a different type.

For example, in the following code the second function is a "clone" of the first, except it accepts strings instead of integers.

func areIntEqual(_ x: Int, _ y: Int) -> Bool {
  return x == y
}

func areStringsEqual(_ x: String, _ y: String) -> Bool {
  return x == y
}

areStringsEqual("ray", "ray") // true
areIntEqual(1, 1) // true

By adopting generics, you can combine the two functions into one and keep type safety at the same time. Here's the generic implementation:

func areTheyEqual<T: Equatable>(_ x: T, _ y: T) -> Bool {
  return x == y
}

areTheyEqual("ray", "ray")
areTheyEqual(1, 1)

Since you're testing equality in this case, you restrict the parameters to any type that implements the Equatable protocol. This code achieves the intended result and prevents passing parameters of a different type.

38.

In some cases, you can't avoid using implicitly unwrapped optionals. When? Why?

The most common reasons to use implicitly unwrapped optionals are:

When you cannot initialize a property that is not nil by nature at instantiation time. A typical example is an Interface Builder outlet, which always initializes after its owner. In this specific case — assuming it's properly configured in Interface Builder — you've guaranteed that the outlet is non-nil before you use it.

To solve the strong reference cycle problem, which is when two instances refer to each other and require a non-nil reference to the other instance. In such a case, you mark one side of the reference as unowned, while the other uses an implicitly unwrapped optional.

39.

What are the various ways to unwrap an optional? How do they rate in terms of safety?

var x : String? = "Test"

Forced unwrapping — unsafe.

let a: String = x!

Implicitly unwrapped variable declaration — unsafe in many cases.

var a = x!

Optional binding — safe.

if let a = x {
  print("x was successfully unwrapped and is = \(a)")
}

Optional chaining — safe.

let a = x?.count

Nil coalescing operator — safe.

let a = x ?? ""

Guard statement — safe.

guard let a = x else {
  return
}

Optional pattern — safe.

if case let a? = x {
  print(a)
}
40.

What's the difference between nil and .none?

here is no difference, as Optional.none (.none for short) and nil are equivalent.

In fact, this statement outputs true:

nil == .none

The use of nil is more common and is the recommended convention.

41.

What’s the value of the len variable, and why?

Consider the following code:

var array1 = [1, 2, 3, 4, 5]
var array2 = array1
array2.append(6)
var len = array1.count

What’s the value of the len variable, and why?

The len variable is equal to 5, meaning that array1 has 5 elements, whereas array2 has 6 elements:

array1 = [1, 2, 3, 4, 5] array2 = [1, 2, 3, 4, 5, 6] When array1 is assigned to array2, a copy of array1 is actually created and assigned.

The reason is that swift arrays are value types (implemented as structs) and not reference types (i.e. classes). When a value type is assigned to a variable, passed as argument to a function or method, or otherwise moved around, a copy of it is actually created and assigned or passed. Note that swift dictionaries are also value types, implemented as structs.

Value types in swift are:

structs (incl. arrays and dictionaries) enumerations basic data types (boolean, integer, float, etc.)

42.

In Swift enumerations, what’s the difference between raw values and associated values?

Raw values are used to associate constant (literal) values to enum cases. The value type is part of the enum type, and each enum case must specify a unique raw value (duplicate values are not allowed).

The following example shows an enum with raw values of type Int:

enum IntEnum : Int {
    case ONE = 1
    case TWO = 2
    case THREE = 3
}

An enum value can be converted to its raw value by using the rawValue property:

var enumVar: IntEnum = IntEnum.TWO var rawValue: Int = enumVar.rawValue A raw value can be converted to an enum instance by using a dedicated initializer:

var enumVar: IntEnum? = IntEnum(rawValue: 1) Associated values are used to associate arbitrary data to a specific enum case. Each enum case can have zero or more associated values, declared as a tuple in the case definition:

enum AssociatedEnum {
    case EMPTY
    case WITH_INT(value: Int)
    case WITH_TUPLE(value: Int, text: String, data: [Float])
}

Whereas the type(s) associated to a case are part of the enum declaration, the associated value(s) are instance specific, meaning that an enum case can have different associated values for different enum instances.

43.

What is capture list?

A capture list is the procedure to handle the references captured in it. By default, Everything will be strongly referenced when you don’t use capture list. Capture lists are defined with a weak or unowned keyword prefix. We need to define a capture variable as weak if it could become nil and the closure won’t be deallocated before then. We need to define a captured reference as unowned if it will never become nil before the closure is deallocated.

44.

What is the difference between garbage collector and ARC?

ARC is technically a form of garbage collection but a deterministic solution: it is predictable as to when it will happen. The languages such as java and C# use garbage collector which is non-deterministic. That means you can’t tell exactly when objects are being reclaimed because it’s being managed by the runtime by an external process.

The main advantage of ARC is that it’s deterministic behaviour and predictable deconstruction. The objects are deallocated immediately when they are no longer needed.

However, ARC can not deal with reference cycles without developer intervention. On the other hand, the main advantage of garbage collector is that it can detect reference cycles.

45.

46.

What is a good use case for an inout parameter?

Function parameters are constants by default. Trying to change the value of a function parameter from within the body of that function results in a compile-time error.

inout means that modifying the local variable will also modify the passed-in parameters. Without it, the passed-in parameters will remain the same value. Trying to think of reference type when you are using inout and value type without using it.

A good use case will be swap function that it will modify the passed-in parameters. Consider removing the overhead of copying as well. If you have a function that takes a somewhat memory-wise large value type as argument (say, a large structure type) and that returns the same type, and finally where the function return is always used just to replace the caller argument, then inout is to prefer as associated function parameter.

47.

What is difference between as?, as! and as in Swift?

Answer In Swift 1.2 and later, as can only be used for upcasting (or disambiguation) and pattern matching: // 'as' for pattern matching

switch item {
case let obj as MyObject:
    // this code will be executed if item is of type MyObject
case let other as SomethingElse:
    // this code will be executed if item is of type SomethingElse
...
}

as? produces an optional value, which is either the value if it can be cast to the specified type, or nil if it can't. as! doesn't produce an optional, it just produces a value of the specified type, and if the cast fails, it aborts the program. Saying foo as! SomeType is basically the same thing as saying (foo as? SomeType)! (except you get a better error message). You should only ever use as! if you're 100% certain the cast will succeed (because if you're wrong, the whole program aborts).

48.

What is a GUARD statement? What is the benefit of using the GUARD statement in swift?

A GUARD statement is used to transfer the program control out of the scope when one or more conditions are not met. Using this statement helps in avoiding the pyramid of doom.

A GUARD statement will be in the following form:

guard condition else { Statements }

49.

What's the difference between Self vs self?

When you’re writing protocols and protocol extensions, there’s a difference between Self (capital S) and self (lowercase S). When used with a capital S, Self refers to the type that conform to the protocol, e.g. String or Int. When used with a lowercase S, self refers to the value inside that type, e.g. “hello” or 556.

As an example, consider this extension on BinaryInteger:

extension BinaryInteger {
    func squared() -> Self {
        return self * self
    }
}

Remember, Self with a capital S refers to whatever type is conforming to the protocol. In the example above, Int conforms to BinaryInteger, so when called on Int the method returns an Int.

On the other hand, self with a lowercase S refers to whatever value the type holds. If the example above were called on an Int storing the value 5 it would effectively be 5 * 5.

50.

When to use strong, weak and unowned references?

  • To determine if you even need to worry about strong, weak, or unowned, ask, “Am I dealing with reference types”. If you’re working with Structs or Enums, ARC isn’t managing the memory for those Types and you don’t even need to worry about specifying weak or unowned for those constants or variables.
  • Strong references are fine in hierarchical relationships where the parent references the child, but not vice-versa. In fact, strong references are the most appropraite kind of reference most of the time.
  • When two instances are optionally related to one another, make sure that one of those instances holds a weak reference to the other.
  • When two instances are related in such a way that one of the instances can’t exist without the other, the instance with the mandatory dependency needs to hold an unowned reference to the other instance.
51.

52.

53.

What is Optional chaining?

Optional chaining is a useful process which we can use in combination with the optional to call the methods, properties, and subscripts on the optionals and these values may or may not be nil. In this process, we may try to retrieve a value from a chain of the optional values.

If the optional contains a value, then calling the subscript, method or property of an optional will return a value. If optional is nil, then calling the subscript, method and property will return nil.

54.

What is Optional binding?

Optional Binding concept is used to find out whether an optional contains a value, and it makes that value available as a variable or temporary constant. We use an optional binding concept to check if the optional contains a value or not.

Optional binding can be used with the condition (if and while) statements to check for a value inside an optional.

55.

When to use class and when to use struct?

As a general guideline, consider creating a structure when one or more of these conditions apply:

  • The structure’s primary purpose is to encapsulate a few relatively simple data values.
  • It is reasonable to expect that the encapsulated values will be copied rather than referenced when you assign or pass around an instance of that structure.
  • Any properties stored by the structure are themselves value types, which would also be expected to be copied rather than referenced.
  • The structure does not need to inherit properties or behavior from another existing type.
  • In all other cases, define a class, and create instances of that class to be managed and passed by reference.
56.

Here's a model of a thermometer as a class and a struct. The compiler will complain about the last line. Why does it fail to compile?

public class ThermometerClass {
  private(set) var temperature: Double = 0.0
  public func registerTemperature(_ temperature: Double) {
    self.temperature = temperature
  }
}

let thermometerClass = ThermometerClass()
thermometerClass.registerTemperature(56.0)

public struct ThermometerStruct {
  private(set) var temperature: Double = 0.0
  public mutating func registerTemperature(_ temperature: Double) {
    self.temperature = temperature
  }
}

let thermometerStruct = ThermometerStruct()
thermometerStruct.registerTemperature(56.0)

The ThermometerStruct is correctly declared with a mutating function to change its internal variable temperature. The compiler complains because you've invoked registerTemperature on an instance created via let, which is therefore immutable. Change let to var to make the example compile.

With structures, you must mark methods that change the internal state as mutating, but you cannot invoke them from immutable variables.

57.

How to pass a variable as a reference?

We can pass variable as a reference using inout parameter. inout means that modifying the local variable will also modify the passed-in parameters.

var value: String = “Apple”
func changeString(newValue:inout String) {
newValue = “Samsung”
print(newValue) // Output:Samsung
print(value) // Output:Samsung
}
changeString(newValue:&value)
58.

What are the different Access Levels in swift?

Swift provides five different access levels for entities within your code.

  • Open access: Classes with open access can be subclassed or overridden by subclasses within the module where they’re defined and within any module that imports the module where they’re defined.
  • Public access: Classes with public access can be subclassed or overridden by subclasses only within the module where they’re defined.
  • Internal access: enables entities to be used within any source file from their defining module, but not in any source file outside of that module.
  • File-private access: restricts the use of an entity to its own defining source file.
  • Private access: restricts the use of an entity to the enclosing declaration, and to extensions of that declaration that are in the same file.

Open access is the highest (least restrictive) access level and private access is the lowest (most restrictive) access level. All entities in your code (with a few specific exceptions) have a default access level of internal.

59.

What is Associated Values?

Associated values are more like variables, associated with one of the enumeration cases.

enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}

“Define an enumeration type called Barcode, which can take either a value of upc with an associated value of type (Int, Int, Int, Int), or a value of qrCode with an associated value of type String.” It is sometimes useful to be able to store associated values of other types alongside case values. This enables you to store additional custom information along with the case value, and permits this information to vary each time you use that case in your code.

60.

Explain generics in Swift ?

enerics enables you to write flexible, reusable functions and types that can work with any type. You can write code that avoids duplication and expresses its intent in a clear, abstracted manner. Swift’s Array and Dictionary types are both generic collections. In below code,generic function for swap two value is used for string and integer. It is the example of reusable code.

func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
var num1 = 4
var num2 = 5
var str1 = “a”
var str2 = “b”
swapTwoValues(&num1,&num2)
swapTwoValues(&str1,&str2)
print (“num1:”, num1) //output: 5
print (“num2:”, num2) //output: 4
print (“str1:”, str1) //output: b
print (“str2:”, str2) //output: a
61.

What is implicit unwrapping?

Implicit Unwrapping : When we define an Implicitly unwrapped optional, we define a container that will automatically perform a force unwrap each time we read it.

var name: String! = “Virat”
let student = name // If now we read text
name = nil
let player = name //fatal error: unexpectedly found nil while unwrapping an Optional value

If an implicitly unwrapped optional is nil and you try to access its wrapped value, you’ll trigger a runtime error. The result is exactly the same as if you place an exclamation mark after a normal optional that doesn’t contain a value.

62.

What are escaping/ nonescaping closures?

@nonescaping closures: (default closure) When you are passing a closure in function’s arguments, using it before the function’s body gets execute and returns the compiler back. When the function ends, the passed closure goes out of scope and have no more existence in memory.

@escaping closures: . When are passing the closure in function’s arguments, using it after the function’s body gets execute and returns the compiler back. When the function ends, the scope of the passed closure exist and have existence in memory, till the closure gets executed.

63.

What is de-initializer and how it is written in Swift?

A de-initializer is declared immediately before a class instance is de-allocated. You write de-initializer with the deinit keyword. Use it if you need to do some action or cleanup before deallocating the object. For example, if you create a custom class to open a file and write some data to it, you might need to close the file before the class instance is deallocated. De-initializer is written without any parenthesis, and it does not take any parameters.

deinit {
// perform the deinitialization
}
64.

What is the difference between Upcast and Downcast in Swift?

The upcast, going from a derived class to a base class, can be checked at compile time and will never fail. However, downcasts can fail since you can’t always be sure about the specific class. If you have a UIView, it’s possible it’s a UITableView or maybe a UIButton. downcasts must be either optional with as? or “forced failable” with as! when sure about the type

65.

What is dispatch queue?

A dispatch queue is responsible for executing a task in the FIFO order.

66.

67.

68.

69.

What will this code print and why?

var thing = "cars"

let closure = { [thing] in
  print("I love \(thing)")
}

thing = "airplanes"

closure()

It'll print: I love cars. The capture list creates a copy of thing when you declare the closure. This means that captured value doesn't change even if you assign a new value to thing.

If you omit the capture list in the closure, then the compiler uses a reference instead of a copy. Therefore, when you invoke the closure, it reflects any change to the variable. You can see this in the following code:

var thing = "cars"

let closure = {    
  print("I love \(thing)")
}

thing = "airplanes"

closure() // Prints: "I love airplanes"
70.

Can you add a stored property to a type by using an extension? How or why not?

No, it's not possible. You can use an extension to add new behavior to an existing type, but not to alter either the type itself or its interface. If you add a stored property, you'd need extra memory to store the new value. An extension cannot manage such a task

71.

What is a protocol in Swift?

A protocol is a type that defines a blueprint of methods, properties and other requirements. A class, structure or enumeration can then adopt the protocol to implement those requirements.

A type that adopts the requirements of a protocol conforms to that protocol. The protocol doesn't implement any functionality itself, but rather defines the functionality. You can extend a protocol to provide a default implementation of some of the requirements or additional functionality that conforming types can take advantage of.

72.

The following code has a compile time error. Can you spot it and explain why it happens? What are some ways you could fix it?

struct Kitten {
}

func showKitten(kitten: Kitten?) {
  guard let k = kitten else {
    print("There is no kitten")
  }   
  print(k)
}

The else block of a guard requires an exit path, either by using return, throwing an exception or calling a @noreturn. The easiest solution is to add a return statement.

func showKitten(kitten: Kitten?) {
  guard let k = kitten else {
    print("There is no kitten")
    return
  }
  print(k)
}

Here's a version that throws an exception.

enum KittenError: Error {
  case NoKitten
}

struct Kitten {
}

func showKitten(kitten: Kitten?) throws {
  guard let k = kitten else {
    print("There is no kitten")
    throw KittenError.NoKitten
  }
  print(k)
}

try showKitten(kitten: nil)

Finally, here's an implementation calling fatalError(), which is a @noreturn function.

struct Kitten {
}

func showKitten(kitten: Kitten?) {
  guard let k = kitten else {
    print("There is no kitten")
    fatalError()
  }
  print(k)
}
73.

Are closures value or reference types?

Closures are reference types. If you assign a closure to a variable and you copy the variable into another variable, you also copy a reference to the same closure and its capture list.

74.

Can you describe a circular reference in Swift? How can you solve it?

A circular reference happens when two instances hold a strong reference to each other, causing a memory leak because neither of the two instances will ever be deallocated. The reason is that you cannot deallocate an instance as long as there's a strong reference to it, but each instance keeps the other alive because of its strong reference.

You'd solve the problem by breaking the strong circular reference by replacing one of the strong references with a weak or an unowned reference.