Swift Interview Questions
What is Swift?
Swift is a multi-paradigm, compiled programming language for designing applications for iOS and macOS, tvOS and watchOS. Apple Inc. is the company behind it. It is a powerful and intuitive language that is also simple to pick up. Swift is an interactive programming language that is quick, safe, and welcoming to new projects. It is based on the Objective C runtime library, which enables the execution of C, Objective C, C++, and Swift code in the same program. Swift has been integrated with Xcode since version 6 and is built with the open-source LLVM compiler and can be used for creating both the front end and back end functionalities of applications.
Swift is the culmination of cutting edge programming language research, as well as decades of expertise developing Apple platforms. Named arguments have a simple syntax that makes Swift APIs (Application Programming Interfaces) considerably easier to learn and manage. Even better is the fact that you do not have to type any semicolons. Modules eliminate headers and offer namespaces, while inferred types make code clearer and less prone to errors. Strings are Unicode correct and use a UTF 8 based encoding to enhance efficiency for a wide range of use cases, so they can handle international languages and emoji. Memory is maintained automatically via strict, deterministic reference counting, which keeps memory usage to a minimum while avoiding garbage collection costs.

Features of Swift:
Let us now take a look at some of the features of the Swift Programming language:
- It is open-source and provides inbuilt error handling.
- Memory management is automatic in Swift. Swift expands on its ObjectiveC predecessor with a mechanism called
- Automatic Reference Counting (ARC). The ARC identifies which class instances are not in use and removes them from developers' workspaces. This frees up time for developers to focus on the application's performance rather than lowering CPU or memory usage.
- Swift provides the feature of Generics that is both effective and easy to use.
- First-class functions and a lightweight closure syntax are present in Swift which makes it easy to store functions in variables and data structures for the ease of coding.
- Extensions in Swift make developing generic code even easier.
- Iteration over a range of collections in a short and simple manner is possible in Swift.
- Swift supports multiple return values and tuples from functions.
- Methods, extensions, and protocols are supported by structures in Swift.
- Payloads of an enum case are allowed in Swift. Also, pattern matching is supported in Swift.
- Exception handling is possible in Swift.
Swift Interview Questions for Freshers
1. What are some features that Swift classes can support but Swift structs cannot?
Given below are some features which Swift classes can support but Swift structs cannot:
- To develop our own custom view controller subclasses, we can inherit from another class, such as UIViewController. This cannot be achieved using Swift structs.
- Before a class is destroyed, it can be deinitialized by calling the deinit() function. This cannot be done for Swift structs.
- Structures are value types, while classes are reference types.
- Value Types: When you copy a value type (for example, when it is assigned, initialised, or passed into a function), each instance preserves its own copy of the data. If you update one instance, it does not affect the other.
- Reference Types: When you copy a reference type, the data is shared among all instances. The reference is copied, but the data it refers to is not. When one is altered, the other is altered as well.
2. How is memory management done in iOS Swift?
Automatic Reference Counting is used by Swift (ARC) in order to do memory management. This is the same thing in Swift as it is in Objective C in terms of notion. When you assign or unassign instances of classes (reference types) to constants, properties, and variables, ARC keeps track of strong references to those instances and increases or decreases their reference count correspondingly. It frees up memory consumed by objects with a reference count of zero. Because value types are copied when assigned, ARC does not raise or decrease its reference count. If you don't declare differently, all references will be strong references by default.
3. Highlight the key difference between Upcast and Downcast in ios Swift.
The key difference between Upcast and Downcast in ios Swift is that upcasting from a derived to a base class can be verified at compile-time and will never fail to compile and Downcasts, on the other hand, can fail to compile since the precise class is not always known. It is possible that the UIView you have is a UITableView or a UIButton.
4. What is the difference between the "==" operator and the "===" operator in ios Swift?
The fundamental difference between the "==" operator and the "===" operator in ios Swift is that the equal to "==" operator compares value types to see if the values are the same while the equivalent to "===" operator compares reference types to see if the references point to the same instance (both point to the same memory address) or not. Let us consider the following example for understanding the difference between the two in a better way:
class Human: Equatable {
let id: Int
let nameOfPerson: String
init(id: Int, nameOfPerson: String) {
self.id = id
self.nameOfPerson = nameOfPerson
}
static func == (left: Human, right: Human) -> Bool {
return left.id == right.id
}
}
let human1 = Human(id: 2, nameOfPerson: "Janvi")
let human2 = Human(id: 2, nameOfPerson: "Janvi")
Now, for the piece of code given below, we can say that the two human instances are equal since their id is the same. Therefore, "Equal Instances!" gets printed.
if human1 == human2 {
print("Equal Instances!")
}else{
print("Instances Not Equal!")
}
Now, for the piece of code given below, we can say that the two human instances are not equivalent even though their id is the same since they point to different areas in the Heap Area, that is, they point to different addresses. Therefore, "Instances are not Equivalent!" gets printed.
if human1 === human2 {
print("Equivalent Instances!")
}else{
print("Instances are not Equivalent!")
}
5. Throw light on some of the differences between Swift and Objective C.
Some of the differences between ios Swift and Objective C are as follows:
Comparison Parameter | ios Swift | Objective C |
---|---|---|
Type of Programming Language. | ios Swift is an object-oriented and functional programming language. | Objective C is a class-based object-oriented programming language. |
Dynamic Libraries | Dynamic Libraries are supported by ios Swift. For instance, system iOS and macOS libraries are dynamic. In other words, these applications will receive improvements from Apple’s updates without new build submission. | Dynamic Libraries are not supported by Objective C. |
Tuples | Tuples are supported by ios Swift. | Tuples are not supported by Objective C. |
Usage of Semicolons | Usage of Semicolons is not mandatory in ios Swift. | Usage of Semicolons is mandatory in Objective C. |
Method definition in Classes, Structures and Enumerations | The definition of methods in Classes, Structures and Enumerations is allowed in ios Swift. | The definition of methods in Classes, Structures and Enumerations is not allowed in Objective C. |
6. List down three ways in which we can append two arrays in ios Swift.
Let us consider that the two arrays are declared as follows:
var firstArray = ["Sonal", "Rahul"]
let secondArray = ["Nawaz", "Riya"]
A thing to be noted is that the first array has been kept mutable so we can append the second array to it. The three ways in which we can append the second array to the first one are as follows:
- Using the method "append(contentsOf: )"- In this method, the contents of the second array are copied into the first array.
firstArray.append(contentsOf: secondArray)
- Using the "+=" operator - In this method also, the contents of the second array are copied into the first array.
firstArray += secondArray
- Appending two arrays by using the "+" operator and adding the result to a new array -
let thirdArray = firstArray + secondArray
7. Explain the various steps (or execution states) involved in the development of an ios Swift application.
The various steps (or execution states) involved in the development of an ios Swift application are as follows:
- Not Running: This is a simple condition in which our program has not been launched or no code has been executed. The program has been terminated by the system.
- Inactive: This is merely a stage in the process of becoming active. Our program is in an inactive state, which means it is running in the background but unable to receive events.
- Active: This is the main execution state, in which our software is running and receiving events.
- Background: This is the condition in which our application is running in the background while still being able to run code.
- Suspended: This state indicates that our application has not been terminated but is present in the background and that the system has suspended it for the time being. Now, the application cannot execute any code.
8. In iOS Swift, what types of objects are considered basic data types?
For various purposes, Swift uses a common set of basic data types such as Boolean values, integers, and strings:
- Int: The integer value is stored in the int variable. Example - 5
- Double and Float: When working with decimal numbers in Swift, double and float are taken into account. Example - 5.78
- Bool: The bool type is used to store the value of a Boolean. True and false conditions are used in Swift. Example - true
- String: In Swift, the user defines the content that is enclosed by double quotes in String literals. Example - "Muskan"
- Arrays: Arrays are collections of objects of the same type from a list. Example - [2,4,11,90,78]
- Dictionaries: A dictionary is an unsorted collection of elements of a specific type linked by a single key. Example - [{name:"Nidhi"}]
9. In Swift, what does the init() method do?
The process of preparing an instance of an enumeration, structure, or class for use is known as initialization. Initializers are also used when a new instance of a type is created. An initializer is a no parameter instance method. The init keyword can be written using the initializer. Their primary role is to ensure that new instances of a type are correctly initialized before they’re used for the first time.
Its syntax is given below:
init()
{
// New Instances are initialized here
}
10. State the control transfer statements present in ios Swift.
The control transfer statements present in ios Swift are as follows:
- Continue: The continue statement skips the current iteration of a loop and directs the program's control flow to the next iteration.
- Break: When the break statement is found, a loop is immediately terminated.
- Return: In Swift, the return statement is used in functions and methods to return values that meet our needs. In the Swift programming language, we can return values from functions/methods based on our requirements by utilising the return keyword.
- Fallthrough: The fallthrough keyword merely directs code execution to the statements contained in the following case (or default case) block.
11. What are some common features in Swift structures and Swift classes?
Some common features in Swift structures and Swift classes are as follows:
- Swift Structs and Swift classes can both define attributes for storing values and functions.
- With init, both structures and classes in Swift can create initializers to set up their initial state ()
- They can be extended using extensions.
- They can follow protocols, such as those used in Protocol Oriented Programming.
- They can collaborate with generics to create types that are adaptable and reusable.
12. List some advantages and disadvantages of using ios Swift.
Some advantages of using ios Swift are as follows:
- It is very fast in terms of execution and both type-safe and memory-safe: Swift is an extremely fast language as far as execution speed is concerned. Also, it is very easy to learn and code in Swift is easy. Type safety refers to the language's ability to prevent type mistakes. Memory safety refers to the absence of flaws caused by uninitialized pointers, which could cause a program to crash. Developers can discover any code flaws with a shorter feedback loop (where outputs are sent back as inputs, which determines the cause and effect of that loop), which reduces debugging time and eliminates the danger of low-quality code.
- Swift is interoperable with Objective C: In Swift, Projects can be written in either Objective C or C++ because they are interoperable. This is particularly beneficial for large projects that are being upgraded when new Swift features are added and subsequently incorporated into the Objective C core.
- Applications made using ios Swift are easy to maintain: Swift makes it simple to maintain an application once it has been built. Swift merges the Objective C header (.m) and implementation files (.h) into a single programme (.swift) file, as opposed to Objective C, which is managed in two separate files. It is worth noting that Swift has dependencies. On macOS, Swift is already installed and ready to use; however, on Linux, you must first install essential dependencies, such as Python and then use it.
- Applications developed using Swift provide a better experience to its users: Swift developed applications take less time to install and consume less on device memory, giving users a better application experience.
-
Swift has efficient memory management: Swift expands on its ObjectiveC predecessor with a mechanism called Automatic Reference Counting (ARC). The ARC identifies which class instances aren't in use and removes them from developers' workspaces. This frees up time for developers to focus on the application's performance rather than lowering CPU or memory usage.
Swift provides Application Binary Interface (ABI) stability: Swift's Application Binary Interface (ABI) is the binary version of the Swift Application Programming Interface (API). While ABI stability is an important accomplishment for any programming language, "the ultimate advantage to the Swift ecosystem was to enable binary compatibility for applications and libraries," according to Swift. In practice, the ABI enables code compiled with multiple versions of Swift, as well as Objective-C, to communicate with one another. - The usage of optionals in Swift: Optionals are a programming technique that allows developers to avoid application crashes because of Null Pointers while maintaining clean code across the application. Consider it a wrapper type that protects the value inside. An optional might be filled with data or left blank. Optionals must be unwrapped to be sure, and if done correctly, will not cause crashes.
Some disadvantages of using ios Swift are as follows:
- Swift is a new language: Swift is a newcomer compared to Objective C, which has been around since the 1980s. Swift came into being in 2014. It may experience growth pains as a result of this. Swift has a restricted set of tools and libraries, despite recent improvements with ABI Stability and backward compatibility. Also, there is not a very big community of ios Swift developers to help the budding ios Swift developers with their problems.
- Binary compatibility does not work every time: Despite the fact that Swift 5.1 has ABI Stability, code generated using multiple versions of Swift can cause issues. Code might have been built as a static library and put into a project as a dependency when developers mostly used Objective C. It was impossible to develop static libraries in Swift prior to the release of Swift's ABI. While this is now possible, including those dependencies in a project poses challenges.
- It is not a Reflective Language: Reflection is a technique that can be used to watch and change the execution of a program while it is running. A reflection oriented software component can track the execution of a code enclosure and adjust its behaviour to meet the enclosure's goals. This is usually performed by assigning programme code dynamically at runtime. Swift is not a reflective programming language in the same way that Java or Kotlin are. Instead, it provides an alternative: the Mirror feature. Swift can "self describe" an object with this, but it can't alter it from within. If Swift had a reflection, it would automatically inject dependencies, however, this is thought to be impossible to achieve.
13. Name the JSON framework which is supported by iOS.
iOS supports the SBJson framework. The SBJson framework adds more control and flexibility to the JSON handling process. It is a well designed and extremely adaptable framework that allows APIs (Application Programming Interfaces) to function in a variety of ways. SBJSON is one of the many open-source JSON parsers or generators created with Objective-C. These allow you to use JSON easily when coding Objective-C apps.
14. What is the use of the "mutating" keyword in ios Swift?
Ios Swift structs are immutable since they are of the value type. Other variables, for example, cannot modify the values of structure at any point in time. Only the "mutating" keyword is necessary to change the values of self variables within the function of the structure. Let us take the following code snippet for example:
struct demoStruct {
var foo: String = "Initial String"
func transformString() {
foo = "Transformed String".
//The above results in a compile time error: Cannot assign to property: 'self' is immutable.
//We need to mark the method 'mutating' to make 'self' mutable.
}
}
We get a compile-time error when we try to alter the value of variable "foo" inside a function declared in the struct itself.
As a result, we will need to create a mutating function to update the value inside the structure. As a result, the correct code is:
struct demoStruct {
var foo: String = "Initial String"
mutating func transformString() {
foo = "Transformed String".
}
}
15. What do you understand about protocols in ios Swift?
The protocol is a concept that is similar to a Java interface and is a highly common component of the Swift programming language. A protocol is a set of attributes, methods, and other requirements that are appropriate for a specific activity. The protocol, in its most basic form, is an interface that describes some methods and characteristics. Instead of implementation, the protocol is described as a skeleton of properties or methods. Enumerations, functions, and classes can be used to implement properties and methods. After the structure, enumeration, or class type names, protocols are declared. It is possible to declare both a single and several protocols. Commas are used to separate multiple protocols.
A protocol can be defined in a similar way to structures, enumerations, and classes:
Protocol demoProtocol
{
// the protocol definition will be going at this place
}
Multiple protocols can be defined by separating them using commas:
Class demoClass: demoSuperclass, protocolOne, protocolTwo
{
// the Structure definition will be going at this place
}
Swift Interview Questions for Experienced
1. What do you understand about Grand Central Dispatch (GDC)?
GCD (Grand Central Dispatch) is a low-level API for controlling several operations at the same time. This notion is employed to aid in the enhancement of application performance. This procedure is used to handle numerous jobs at once. The most relevant API for multitasking with Async and Sync programming in iOS is Grand Central Dispatch (GCD).
- Dispatch Queue: The task is managed in FIFO (First In First Out) order by the Dispatch Queue. Dispatch queues are thread-safe because they can be accessed by several threads at the same time.
- Concurrent: This process has started numerous tasks at the same time but does not know when they will finish. It can be completed in whatever sequence you want. They perform one or more things concurrently at the same time. The work is finished in the order in which it was queued, not in the order in which it was completed.
- Serial: A single task will be executed at a time. It is possible to use it to synchronize access to a certain resource.
- Sync: After the work is completed, a synchronous function returns control to the caller.
- Asynchronous: An asynchronous function returns instantly after ordering a job to begin but does not wait for it to finish.
2. State your understanding of delegates in ios Swift.
Delegate, in ios Swift, is a design pattern that allows data or communication to be passed across structs or classes. Delegate allows one object to deliver a message to another when a certain event occurs, and it is used to handle table and collection view events. Delegates have a one on one interaction and communicate with one another.
An example of a delegate is given below:
// Defining a custom delegate known as SeeActionDelegate
protocol SeeActionDelegate {
// Defining the required delegate variables
var state: GetState { get }
var userIdentity: String? { get set }
// Defining the required delegate blocks
var errorHandler: ((Error) -> Void)? { get set }
// Defining the required delegate functions
func handle(action: GetAction)
}
The enums used in the above delegate are:
enum GetState {
case `default`
case loading
}
enum GetAction {
case saved
case canceled
}
3. How can the double question mark symbol "??" be used in ios Swift programming?
The nil-coalescing operator "??" is a shorthand for the ternary conditional operator, which we used to test for nil. A double question mark can also be used to set a variable's default value.
"default string" stringVar??
This does precisely what you would expect: if stringVar is not nil, it is returned; otherwise, the "default string" is returned.
4. What is the meaning of a GUARD statement? What are the advantages of using Swift's GUARD statement?
When one or more conditions are not met, a GUARD statement is used to transfer program control out of the scope. This remark aids in avoiding the doomsday pyramid. The following is the syntax of a GUARD statement:
guard condition else
{
Statements
}
5. What do you understand about generics in ios Swift?
Generics are a way to avoid code duplication. It is usual to repeat a method that takes one type of parameter to accommodate a parameter of a different type. Generics can be used in both functions and data types in Swift, such as classes, structures, and enumerations.
func integerEquality(_ a: Int, _ b: Int) -> Bool {
return a == b
}
func stringEquality(_ a: String, _ b: String) -> Bool {
return a == b
}
stringEquality("hello", "hello") // returns true
integerEquality(5, 5) // returns true
For example, the second function in the above code is a "clone" of the first, but it accepts texts rather than numbers.
func commonEquality<T: Equatable>(_ a: T, _ b: T) -> Bool {
return a == b
}
commonEquality("hello", "hello") // returns true
commonEquality(5, 5) // returns true
You can consolidate the two functions into one and maintain type safety at the same time by using generics. Given above is the way to do it in general.
Because you are testing equality here, you can use any type that implements the Equatable protocol as a parameter. This code achieves the desired outcome while preventing the use of non-typed parameters.
6. What do you understand about optionals in ios Swift? What is the problem which they solve?
An optional, in ios Swift, allows any type of variable to reflect a lack of value. The absence of value in Objective C is only available in reference types that use the nil special value. This is not possible with value types like int or float.
With optionals, ios Swift extends the absence of value ideas to both reference and value types. An optional variable can be set to either a value or nil, which indicates that it has no value. An example of an optional is given below:
var text: String?
text = "I will go to school."
print(text)
7. What are a few scenarios in which we can't avoid using implicitly unwrapped optionals and why so?
The following are the most prevalent reasons for using implicitly unwrapped optionals:
- When you can't initialise a property that is not nil (absence of value) by definition at the moment of instantiation. An Interface Builder outlet, for example, is always initialised after its owner. In this case, you have ensured that the outlet is non-nil before using it, provided it's properly configured in Interface Builder.
- To tackle the problem of a strong reference cycle, which occurs when two instances refer to each other and one of them requires a non-nil reference to the other. In this situation, one side of the reference is marked as unowned, while the other employs an implicitly unwrapped optional.
8. In Swift, how would you describe a circular reference? What are your options for resolving it?
When two instances have a strong connection to one other, a circular reference occurs, resulting in a memory leak because neither of the two instances will ever be deallocated. The reason for this is that you can't deallocate an instance if it has a strong reference to it, yet each instance maintains the other alive due to the strong reference. This might lead to a deadlock which is extremely bad for the application.
Breaking the strong circular reference by replacing one of the strong references with a weak or unowned reference would fix the problem of a circular reference.
9. State your understanding of core data.
Apple's Core Data framework is one of the most powerful frameworks for macOS and iOS programmes. In our applications, core data is used to manage the model layer object. Within iOS applications, we may use Core Data as a framework to filter, alter, save, and track data. Core Data is not a relational database in the traditional sense. Without learning SQL, we can easily connect the objects in our app to the table records in the database using core data. The M in the MVC structure stands for core data.
Some features of Core data are listed below:
- Integration with the iOS and macOS toolchains is seamless.
- Data organisation, filtering, and grouping in memory and in the user interface (User Interface).
- Object storage is supported automatically.
- Property values are validated automatically.
- The first object graph management framework.
- The object graph's life cycle is managed using the Core Data framework.
10. What are the several methods for unwrapping an optional in Swift?
The several methods for unwrapping an optional in Swift are as follows:
-
Forced unwrapping: It consists in adding a ! after an Optional value, to automatically unwrap it, without having to check whether it is nil or not. Example - let v:String = b!
Optional chaining: The technique of querying and calling properties, methods, and subscripts on an optional that is currently nil is known as optional chaining. The property, method, or subscript call succeeds if the optional includes a value; if the optional is nil, the property, method, or subscript call returns nil. Multiple inquiries can be chained together, and if any link in the chain is nil, the entire chain will fail gracefully. Example -
let v = b?.count
- Nil coalescing operator: If there is a value inside an optional, the nil coalescing operator unwraps it and returns it. If no value is provided – for example, if the optional is nil – a default value is used instead. The result will not be optional in either case: it will be either the value from within the optional or the default value used as a backup. Example -
let v = b ?? ""
- Optional pattern: An optional pattern matches items wrapped in an Optional<Wrapped> enumeration's some(Wrapped) case. Optional patterns appear in the same places as enumeration case patterns and consist of an identifier pattern followed by a question mark. An example is given below:
if case let v? = b {
print(v)
}
- Guard statement: When certain requirements are not met, the guard statement in Swift is used to shift program control out of scope. With one key exception, the guard statement is comparable to the if statement. When a given condition is met, the if statement is executed. The guard statement, on the other hand, is executed when a given condition is not met. Example is given below:
guard let v = b else {
return
}
- Optional binding: Optional binding is used to determine whether or not an optional has a value. If it does have a value, unwrap it and save it in a temporary variable or constant. Example is given below:
if let v = b {
print("b has been unwrapped with success and is = \(v)")
}
- Implicitly unwrapped variable declaration: Because a variable may start life as nil, but will always have a value before you need to use it, implicitly unwrapped optionals exist. It's helpful not to have to write if let all the time because you know they'll have value by the time you need them. Example:
var v = b!
11. What is a Swift module?
A single unit of code distribution in ios Swift is referred to as a module. The Swift "import" keyword can be used to import a framework or application that has been created and shipped as a single unit. In Swift, each Xcode build target is treated as an independent module. An example of using the "import" keyword is given below:
import UIKit
12. Explain the difference between Self and self in ios Swift.
There is a distinction between Self (capital S) and self (small S) when writing protocols and protocol extensions. When used with a capital S, Self refers to the protocol compliant type, such as String or Int. When used with a lowercase S, self refers to the value contained within that type, such as "hi" or 999, for instance.
Consider the following SquareInteger extension as an example:
extension SquareInteger {
func squareANumber() -> Self {
return self * self
}
}
Remember that Self with a capital S refers to any type that follows the protocol. Because Int conforms to SquareInteger in the example above, when called on Int, the method returns an Int. Self with a lowercase S, on the other hand, refers to the type's current value. If the preceding example were run on an Int containing the value 4, the result would be 4 * 4.
13. What do you understand about PLIST in ios? List some examples of types of PLIST.
The abbreviation PLIST in ios stands for Property List. PLIST is a value and key dictionary that can be saved in our file system using the .plist file extension. The property list is used to store a smaller quantity of data in a portable and lightweight manner. In most cases, they are written in XML.
The following are examples of several sorts of property lists:
- Binary Property List
- XML Property List
14. ASCII Legacy Property ListQuestion: What do you understand about training closure syntax in ios Swift?
Many iOS Swift functions accept multiple parameters, the last of which is a closure. Trailing closure syntax is a small amount of syntactic sugar that makes reading and writing common code easier.
For example, consider the following code snippet:
func RunClosureAfterGreeting(name: String, closure: () -> ()) {
print("Hi, \(name)!!!")
closure()
}
Instead of the above code snippet, we can write the following code (which is way cleaner than the previous one):
RunClosureAfterGreeting(name: "Sonia") {
print("The closure has been run")
}
15. Explain Protocol Vs Class in ios Swift.
- A protocol, in its most basic form, explains what an unknown sort of object can accomplish. It has two or three different sorts of properties, as well as procedures. Protocol never includes anything inside the methods, nor does it provide actual storage for the properties. You can build extensions to your protocols that give default implementations of the methods in a more advanced form. However, you are still unable to provide storage for properties.
extension Car : CustomStringConvertible {
var description : String { get { return "Car: \(colour)" } }
}
- Classes are tangible objects. They are not needed to embrace protocols, which means they do not have to implement the required attributes and methods. Classes can be used to generate objects, whereas protocols are simply typed declarations. Consider protocols to be abstract definitions, whereas classes and structs are actual objects that can be created. An example of a class is given below:
class Car {
var colour: String
}
16. How should one consider the usage of strong, weak and unowned references?
Ask yourself, "Am I dealing with reference types?" to see if you need to worry about strong, weak, or unowned. If you are working with Structs or Enums, ARC is not in charge of memory management, so you do not have to worry about defining weak or unowned constants or variables.
In hierarchical relationships, strong references are acceptable when the parent refers to the child, but not when the child refers to the parent. Strong references are, in fact, the most appropriate type of reference the majority of the time.
If two instances are optionally linked, make sure one of them has a weak reference to the other.
When two instances are linked to the point where one cannot exist without the other, the instance with the obligatory dependency must keep an unowned reference to the other instance.

17. When is the usage of a set more preferable than an array in ios Swift?
If all of the following conditions are met, you should use a set rather than an array:
- You only want to add each item once. Duplicates are never permitted in sets.
- The order of the items in the collection is irrelevant to you.
- You are storing Hashable types, either your own or those provided by Swift, such as strings and integers. Hash values are used in sets to look for things quickly.
18. Show the use of "self" in a method using an example.
In Swift, the self property of an instance is a special property that holds the instance itself. In most cases, self appears in a class, structure, or enumeration's initializer or method. The most common use of self is in initializers when you are likely to want parameter names that match your type's property names, such as this:
struct student {
var myName: String
var myFriend: String
init(myName: String, myFriend: String) {
print("\(name) is being enrolled in class...")
self.myName = myName
self.myFriend = myFriend
}
}
19. How can we use the "inout" parameter in ios Swift? Explain with an example.
By default, function parameters are constants. Changing the value of a function parameter from within the function's body causes a compile-time error. Modifying the local variable also modifies the passed in arguments, which is known as the "inout" parameter. The passed-in arguments will have the same value if it is not present. Trying to remember the reference type while using inout and the value type when not using it. The swap function, which modifies the parameters handed in, is an excellent example. Consider reducing the copying overhead as well. If you have a function that takes a memory-intensive large value type as an argument (say, a huge structure type) and returns the same type, and the function return is only used to replace the caller argument, the inout parameter is the associated function parameter to use. As we can see in the example given below, a call to the function "demoFunction" copies arguments to function property 'aBigStruct'(copy 1) and the function property is mutated after which, the function returns a copy of the mutated property to the caller (copy 2). However, in the function "demoFunctionWithLessCopyOverhead", call by reference is being done and zero value copy overhead is there because of the usage of inout optimization.
struct demoStruct {
private var counter: Int = 1
// ... a lot of stored properties
mutating func incrementCounter() {
counter += 1
}
}
/* call to this function copies argument to function property 'aBigStruct'(copy 1)
function property is mutated
function returns a copy of mutated property to caller (copy 2) */
func demoFunction(var aBigStruct: MyStruct) -> MyStruct {
aBigStruct.incrementCounter()
return aBigStruct
}
/* call by reference -> zero value copy overhead because of the inout optimization */
func demoFunctionWithLessCopyOverhead(inout aBigStruct: MyStruct) {
aBigStruct.incrementCounter()
}
var ex = MyStruct()
ex = demoFunction(ex) // copy, copy: overhead
demoFunctionWithLessCopyOverhead(&ex)
// call by reference: no memory reallocation
Swift Programming
1. Let us take into consideration the following code snippet in ios Swift:
struct Course{
var toughness: Int = 3
}
var courseOne = Course()
var courseTwo = courseOne
courseTwo.toughness = 4
What will be the respective values of courseOne.toughness and courseTwo.toughness? If Course was a class instead of a struct, would the values be any different?
The value of courseOne.toughness will be 3 and the value of courseTwo.toughness will be 4 if Course is a structure since Structures in ios Swift are value types and the following line just copies the courseOne to courseTwo by value and not by reference:
var courseTwo = courseOne
If Course was a class instead of a struct, then the above given line would copy courseOne to courseTwo by reference and therefore, the values of both courseOne and courseTwo would be 4 by the end of the code snippet as they have the same address. Classes in ios Swift are Reference types therefore both the given courses have the same address.
2. In the given code snippet, we have used var to declare viewOne and let to create viewTwo. Will the last line compile?
import UIKit
var viewOne = UIView()
viewOne.alpha = 0.7
let viewTwo = UIView()
viewTwo.alpha = 0.7 // Does this line compile?
The last line will, in fact, compile. viewOne is a variable that we can reassign to a new UIView object. Because we can only assign a value once with let, the following code will not compile:
viewTwo = viewOne // Error: viewTwo is immutable
However, because UIView is a reference-based class, we can change the properties of viewTwo — which means the following code will compile:
let viewTwo = UIView()
viewTwo.alpha = 0.7 // Yes, this compiles!
3. Take a look at the code snippet given below. Will the given code fail to compile? If yes, why?
public class TemperatureClass {
private(set) var temp: Double = 50.0
public func changeTemperature(_ temp: Double) {
self.temp = temp
}
}
let temperatureClass = TemperatureClass()
temperatureClass.changeTemperature(72.3)
public struct TemperatureStruct {
private(set) var temp: Double = 50.0
public mutating func changeTemperature(_ temp: Double) {
self.temp = temp
}
}
let temperatureStruct = TemperatureStruct ()
temperatureStruct.changeTemperature(72.3)
Yes, the code given will fail to compile because of the last line of the code. The TemperatureStruct has a mutating method to change its internal variable temp, which is correctly declared. Because we called changeTemperature on an object generated using let, which is immutable, the compiler gives an error. To make the example compile, change let to var.
Methods that affect the internal state of a structure must be marked as mutating, but they cannot be invoked from immutable variables.
4. Predict the output of the following ios Swift program:
var item = "apples"
let closure = { [item] in
print("He wanted to eat \(item)")
}
item = "oranges"
closure()
The output of the given code snippet will be "He wanted to eat apples". When we define the closure, the capture list generates a duplicate of the item. This means that even if you modify the value of an object, the captured value remains the same.
5. Predict the output of the ios Swift code snippet given below
var item = "apples"
let closure = {
print("He wanted to eat \(item)")
}
item = "oranges"
closure()
The above-given code snippet prints "He wanted to eat oranges". If you do not include a capture list in the closure, the compiler will use a reference rather than a copy. As a result, any change to the variable is reflected when the closure is invoked.
6. Take into consideration the following struct:
public struct Temperature{
public var temp: Double
public init(temp: Double) {
self.temp = temp
}
}
Can we do an initialization using the following code:
var temp: Temperature = 60.5
Yes, Swift specifies protocols that allow you to use the assignment operator to initialize a type with literal values. Literal initialization of a certain type is possible by adopting the corresponding protocol and supplying a public initializer. You implement ExpressibleByFloatLiteral as follows in the example of Temperature:
extension Temperature: ExpressibleByFloatLiteral {
public init(floatLiteral value: FloatLiteralType) {
self.init(temp: value)
}
}
After this, we can do the above-given initialization without any errors.
7. To conduct arithmetic or logic tasks, Swift offers a collection of predefined operators. It also enables for the construction of bespoke unary and binary operators.
Define and implement a custom power ^^ operator that satisfies the following requirements:
- As arguments, it accepts two Ints.
- The first parameter is returned after raising it to the second parameter's power.
- The equation is correctly evaluated using the conventional algebraic sequence of operations.
- Overflow errors are not taken into account.
There are two steps to creating a new custom operator:
- Declaration: The "operator" keyword is used in the declaration to indicate the type of the operator (unary or binary), the sequence of letters that make up the operator, associativity, and precedence. The operator here is ^^ and the type is infix (binary) in this case. Equal precedence operators ^^ should evaluate the equation from right to left (associativity is right). The following is the declaration step:
precedencegroup ExponentPrecedence {
higherThan: MultiplicationPrecedence
associativity: right
}
infix operator ^^: ExponentPrecedence
- Implementation: In Swift, there is no set precedence for exponential operations. Exponents should be calculated before multiplication and division in the normal algebra sequence of operations. As a result, you will need to set custom precedence that puts them ahead of multiplication. The following is the implementation step:
func ^^(base: Int, exponent: Int) -> Int {
let left = Double(base)
let right = Double(exponent)
let powerValue = pow(left, right)
return Int(powerValue)
}
It can be noted that as the program does not take overflows into consideration, in the event of the operation producing a result that Int can't represent, for example, a value more than Int.max, then a runtime error occurs.
8. You are on a two-dimensional infinite grid where you can move in any of the eight directions (x,y) to (x-1, y-1), (x-1, y), (x-1, y+1), (x , y-1), (x , y+1), (x+1, y-1), (x+1, y) , (x+1, y+1).
You are given a list of points to cover and the order in which you must do so. Write an ios Swift code to give the shortest number of steps you can take to achieve it. You begin from the first point of the given list.
Because the order in which the points are covered is already known, the problem is reduced to figuring out how to calculate the distance between two points (A, B) and the distance between two points (A, B) and the distance between two points (A, B) and the distance between two points (A, B) and the distance between two points (A, B) and the distance (C, D). It is worth noting that just X = abs(A-C) and Y = abs(A-C) are important (B-D). You will progress along the diagonal while X and Y are both positive, and X and Y will both decrease by one. When one of them reaches zero, you move on to the next stage, reducing the remaining number by one. In other words, the total number of steps would be equal to the maximum number of steps (X, Y)
The code in ios Swift to solve this given problem is given below:
import Foundation
class Solution {
func coverEveryPoint(_ X: inout [Int], _ Y: inout [Int]) -> Int {
if X.count != Y.count || X.count == 0 || X.count == 1 {
return 0
}
var dist = 0
for j in 0 ..< X.count - 1 {
let xOne = X[j]
let yOne = Y[j]
let xTwo = X[j + 1]
let yTwo = Y[j + 1]
dist += distanceFinder((xOne , yOne), (xTwo, yTwo))
}
return dist
}
func distanceFinder(_ X: (x: Int, y: Int), _ Y: (x: Int, y: Int)) -> Int {
return (abs(X.y - Y.y) - abs(X.x - Y.x)) > 0 ? abs(X.y - Y.y) : abs(X.x - Y.x)
}
}
9. There is a compile time error in the following code. Are you able to recognise it and explain why it occurs? What are some possible solutions?
struct Cat{
}
func showCat(cat: Cat?) {
guard let c = cat else {
print("No presence of cat")
}
print(c)
}
The problem with the given code is that a guard's else block requires an escape path, which can be achieved by returning, throwing an exception, or calling a @noreturn. Adding a return statement is the simplest approach:
func showCat(cat: Cat?) {
guard let c = Cat else {
print("No presence of cat")
return
}
print(c)
}
A fatalError() can also be called which is a @noreturn function:
struct Cat{
}
func showCat(cat: Cat?) {
guard let c = Cat else {
print("No presence of cat")
fatalError()
}
print(c)
}
10. This below given difficult code sorts an array of fruits. Write down ways to code the given logic in a simpler way than the code given below.
var fruits = ["apples", "oranges", "papaya", "kiwi"]
fruits.sort { (a: String, b: String) -> Bool in
return a < b
}
print(fruits)
There are three ways in which we can simplify the given code snippet:
fruits.sort { (a,b) in return a < b }
fruits.sort { $0 < $1 }
fruits.sort(by: <)
Conclusion:
Apple gadgets are used by billions of people all over the world. The number of iOS users has been constantly increasing, which is good news for iOS application developers. iOS Swift developers must also keep up with the latest developments in the iOS Swift community. Make sure you are keeping up with Apple developer news, podcasts, and blogs. This is unlikely to be a question in an interview, but it distinguishes you. We hope that the Swift Interview questions answered here are extremely helpful in studying the fundamentals and advanced topics of iOS Swift. Any beginner or experienced professional who understands these Swift and iOS developer interview questions will be able to pass the interview on the first try. All the best for your upcoming interviews!
Swift MCQ
Functions in ios Swift can be of how many types?
Which of the following is not a control transfer statement used in iOS Swift?
In order to reference class members from within the class in iOS Swift, which of the following can be used?
The number of times do the following loop executes in iOS Swift is?
for j in 3...103{
print(j)
}
We can declare variables in iOS Swift using the __ keyword and we can declare constants in iOS Swift using the ___ keyword.
What is the question mark symbol "?" in iOS Swift used for?
When a closure is being taken as a parameter by a function, when should it be marked as escaping?
Which of the following can be declared in code to make a property optional in iOS Swift?
Which of the following features does the Switch statement in iOS Swift have?
Which of the following is called by a convenience initializer in iOS Swift?