Interview Questions and Answers in iOS — Part 1

Interview Questions and Answers in iOS

Q. What is Objective C?
A. Objective C is a simple computer language designed to enable sophisticated object-oriented programming.

Objective C is a very dynamic language that means we don’t have to tell the compiler what type of object we are going to work with at compile time.

Objective C is dynamic because of three dynamic feature:
1) Dynamic Typing: Determining the class of an object at runtime.
2) Dynamic Binding: Determining the method to invoke at runtime.
3) Dynamic Loading: Adding new modules to a program at runtime.

Q. Who invented Objective C?
A. Broad Cox and Tom Love in the 1980s.

Q. What is Class?
A. A class is meant to define an object and how it works.
A class is like a blueprint or a prototype or a set of instructions to build a specific type of object.
A class defines the variables and the methods (functions) common to all objects of a certain kind.

class <class_name> {  
field/variable;
method/function;
}

Q. What is Object?
A. An object is an instance of a class. Object determines the behavior of the class. When we send a message to an object, we ask the object to invoke or execute one of its methods.

ClassName instance = ClassName();

Q. What is Cocoa?
A. Cocoa is an application environment for both mac os & ios. It consists of suits of object-oriented libraries, runtime systems, and an IDE.

Q. What is method calling?
A. Communication between the sender and receiver. A sender may be an object or class name and the receiver may be a method(+ or — type).

Q. Difference between the Instance Methods and Class Methods?
A. Instance methods call through the object of the class or by self (if in the same class).
Class methods call through the name of the class.

Q. What happens when we invoke a method on a nil pointer in Objective C?
A. A message sent to a nil object is perfectly acceptable in Objective-C. it’s treated as a no-op.

Q. Static and Dynamic Typing?
A. Static typed languages are those in which type checking is done at compile time whereas dynamic typed languages are those in which type checking is done at runtime.
Objective C is a dynamic typed language that means we don’t have to tell the compiler what type of object we are going to work with at compile time.

Q. Which method and function are called first when any iOS application starts?
A.
The first function called during app launch

int main(int argc, char *argv[])

First AppDelegate method called during app launch

application(_:willFinishLaunchingWithOptions:)

UIKit handle most of app launch tasks.

  1. The app is launched, either explicitly by the user or implicitly by the system.
  2. The Xcode-provided main function calls UIKit's UIApplicationMain(_:_:_:_:) function.
  3. The UIApplicationMain(_:_:_:_:) function creates the UIApplication object and your app delegate.
  4. UIKit loads your app’s default interface from the main storyboard or nib file.
  5. UIKit calls your app delegate’s application(_:willFinishLaunchingWithOptions:) method.
  6. UIKit performs state restoration, which calls additional methods of your app delegate and view controllers.
  7. UIKit calls your app delegate’s application(_:didFinishLaunchingWithOptions:) method.

When initialization is complete, the system uses either our scene delegates or app delegate to display your UI and manage the life cycle for your app.

Reference:
https://developer.apple.com/documentation/uikit/app_and_environment/responding_to_the_launch_of_your_app/about_the_app_launch_sequence

Q. Explain App States?
A. At any given moment, our app falls into one of the below given states.

Not Running: App has not been launched or terminated by the system.

Inactive: The app is running in the foreground but is currently not receiving any event. This could happen in case a Call or Message is received. An application could also stay in this state while in the transition to a different state. In this State, we can not interact with the app’s UI.

Active: The app is running in the foreground and receiving events. This is the normal mode for the Foreground apps. The only way to go to or from the Active state is through the Inactive state. A user normally interacts with UI and can see the response/result for user actions.

Background: App is in the background and executing code. Freshly launched apps directly enter into In-Active state and then to Active state. Apps that are suspended, will come back to this background state, and then transition to In-Active → Active states.

Suspended: App is in the background but not executing code. The system moves the application to this state automatically and does not notify. In the case of low memory, the system may purge suspended applications without notice to make free space for the foreground application. Usually, after 5 secs spent in the background, apps will transition to Suspend state, but we can extend the time if the app needs.

App States

Q. What is the use of the UIApplication Class?
A. The UIApplication class implements the required behavior of an application.
UIApplication class defines some methods which are called or will be responded to some of the above states.

Q. UIApplication Delegate?
A. application:willFinishLaunchingWithOptions: This method is called after our application has been launched successfully. It is the first method from our app delegate, which gets called. We can execute our code if the launch was successful.

application:didFinishLaunchingWithOptions: This method is called before the app’s window is displayed. We can finalize our interface and can provide the root ViewController to the window.

applicationDidBecomeActive: This method is either called to let our app know that it moved from the inactive to active state or our app was launched by the user or the system or in case user ignores an interruption (such as an incoming phone call or SMS message) that sent the application temporarily to the inactive state. We should use this method to restart any tasks that were paused (or not yet started) while the app was inactive.

applicationWillResignActive: This method is called to let our app know that it is about to move from active to inactive state. This can happen in case of any interruptions (such as an incoming phone call or SMS message or Calendar alerts) or when the user quits the app. We should use this method to pause any ongoing tasks or disable timers etc.

applicationDidEnterBackground: This method is called to let the app know that it is not running in the foreground. We have approximately five seconds to perform any task and return back. In case we need additional time, we can request additional execution time from the system by calling beginBackgroundTask(expirationHandler:). If the method does not return before time runs out then our app is terminated and purged from memory. applicationWillResignActive method is called before this method.

applicationWillEnterForeground: This method is called as a part of the transition from the background to the active state. We should use this to undo any change we made to our app upon entering the background. applicationDidBecomeActive method is called soon after this method has finished its execution which then moves the app from the inactive to the active state.

applicationWillTerminate: This method is called to let our app know that it is about to terminate. We should use this method to perform any final clean-up task. This method may be called in situations where the app is running in the background (not suspended) and the system needs to terminate it for some reason. We shouldn’t wait for applicationWillTerminate to be called in order to save our data. There are some cases when applicationWillTerminate won’t be called before app termination. For example, the system will not call applicationWillTerminate when the device reboots.

Q. UIViewController lifecycle methods?
A. There are three ways to create UI (Which attached to a viewController class).
1. From the .xib
2. From Code
3. By Storyboard

Lifecycle Methods:

UIViewController Lifecycle

loadView: This method is called to loads or creates the view for the view controller.
We should never call this method directly. The view controller calls this method when its view property is requested but is currently nil.
If the view controller has an associated nib file, this method loads the view from the nib file. If the view controller does not have an associated nib file, this method creates a plainUIView object instead.
We can override this method in order to create our views manually.
If we are working with storyboards or nib files, then we do not have to do anything with this method and we can ignore it.

viewDidLoad: This method is called when the view is loaded into memory, whether from a Xib file, storyboard or programmatically created in loadView.
When this method gets called, the view of the view controller has been created and we are sure that all the outlets are in place.
This method is called only once in the lifetime of a view controller, so we use it for things that need to happen only once.
This method call before the bounds are defined and rotation happens. So it is risky to work with the view’s size in this method.

viewwillAppear: This Method is called every time before the view is visible to and before any animation is configured.
We override this method for tasks that we need to repeat every time a view controller comes on screen. This method can be called multiple times for the same instance of a view controller.
Notifies the view controller that its view is about to be added to a view hierarchy.
In this method view has bound but orientation is not set yet.

viewDidAppear: This method is called after the view controller appears on the screen.
We can use it to start animations in the user interface, to start playing a video or a sound, or to start collecting data from the network.

viewWillLayoutSubviews: This method is called to notify the view controller that its view is about to layout its subviews.
This method is called every time the frame changes like for example when rotating or it’s marked as needing layout.

viewDidLayoutSubviews: This method is called to notify the view controller that its view has just laid out its subviews. We make additional changes hereafter the view lays out its subviews.

viewWillDisappear: This method is called before the transition to the next view controller happens and the origin view controller gets removed from the screen. This means, the view is still on view hierarchy but not removed yet.
We add code here to handle timers, hide the keyboard, to cancel network requests, revert any changes to the parent UI. Also, this is an ideal place to save the state.

viewDidDisappear: This method is called after the VC’s view has been removed from the view hierarchy.
We usually override this method to stop tasks that are should not run while a view controller is not on screen. For example, stop listening to notifications, monitoring the device sensors, or a network call that is not needed anymore.

deinit(): Before a view controller is removed from memory, it gets deinitialized. We usually override deinit() to clean resources that the view controller has allocated that are not freed by ARC.
Keep in mind that just because a VC is no longer visible, doesn’t mean that it has been deallocated. Container view controllers such as NavigationController can keep their VCs available in memory. Keep in mind that even though a VC is off-screen, if it is still in memory, it still works normally and can receive notifications. Sometimes this is desirable, other times it isn’t, so we need to keep this in mind while developing our app.

didReceiveMemoryWarning(): When the memory starts to fill up, iOS does not automatically move data from memory to its limited hard disk space. It does, however, issue this warning and WE are responsible for clearing some objects out of memory. Be aware that if the memory of our app goes over a certain threshold, iOS will shut down our app. Unfortunately, this will look like a crash to the end users.

viewWillTransition(to: with:): When the interface orientation changes, UIKit calls this method on the window’s root view controller before the size changes are about to be made. The root view controller then notifies its child view controllers, propagating the message throughout the view controller hierarchy.

Q. What is the difference between viewDidLoad and viewDidAppear? Which should we use to load data from a remote server to display in the view?
A. viewDidLoad is called when the view is loaded into the memory, whether from a Xib file, storyboard or programmatically created in loadView.
viewDidAppear is called every time the view is presented on the device.

Which to use depends on the use case for our data. If the data is fairly static and not likely to change then it can be loaded in viewDidLoad and cached. However, if the data changes regularly then using viewDidAppear to load it is better. In both situations, the data should be loaded asynchronously on a background thread to avoid blocking the UI.

Q. setNeedsLayout vs layoutIfNeeded vs layoutSubviews()?
A.
- setNeedsLayout()
The method setNeedsLayout for a UIView tells the system that we want it to layout and redraw that view and all of its subviews when it is time for the update cycle. This is an asynchronous activity.

- layoutIfNeeded() The method layoutIfNeeded for a UIView tells the system that we want it to layout and redraw that view and all of its subviews, and we want it done immediately without waiting for the update cycle. This is a synchronous activity.

- layoutSubviews() The default implementation uses any constraints we have set to determine the size and position of any subviews.
Subclasses can override this method as needed to perform a more precise layout of their subviews. We should override this method only if the auto-resizing and constraint-based behaviors of the subviews do not offer the behavior we want. We can use our implementation to set the frame rectangles of our subviews directly.
We should not call this method directly. If we want to force a layout update, we should call the setNeedsLayout() method. If we want to update the layout of our views immediately, we should call the layoutIfNeeded() method.

Q. Difference between the Frame and Bound?
A. Frame: The frame of a UIView is the rectangle expresses as a location(x, y) and size(width, height) relative to the super view it is contained within.

Bound: The bound of a UIView is the rectangle expresses as a location(x, y) and size(width, height) relative to its own coordinate system. Or frame with respect to its own.

Q. Difference between the alloc and new method?
A. alloc and new methods are defined in the NSObject class. alloc creates a new memory location but doesn’t initialize it as compared to new. To initialize new memory location with alloc method, we use init method of NSObject class.
Alloc: Class method of NSObject. Returns a new instance of the receiving class.
Init: Instance method of NSObject. Implemented by subclasses to initialize a new object (the receiver) immediately after memory for it has been allocated.
New: Class method of NSObject. Allocates a new instance of the receiving class, sends it an init message and returns the initialized object.
new = alloc + init

Q. What is Property?
A. Property is used to provide a simple way to declare and implement an object’s accessor methods(getter & setter).
The compiler synthesizes accessor methods for us according to the specification provided in the declaration.

@property int result;
-(void)setResult:(int)variable;
-(int)getResult;

Q. @synthesize and @dynamic in Objective C?
A. @synthesize: We use this directive to tell the compiler that it should synthesize the setter and getter methods for the property.

@dynamic: We use this directive to tell the compiler that setter and getter methods are not implemented by the class but by some other class may be a superclass or child class or will be provided at runtime.
In the Core Data framework, the NSManagedObject class has a property defined by using @dynamic directive.

Q. What is @synthesize in Objective-C?
A. Synthesize directive generates getter and setter methods for our property.

Q. Implement your own synthesized methods for the property NSString *title?
A.

-(NSString)getTitle
{
return title;
}
-(void)setTitle:(NSString *)newTitle
{
if(newTitle != title)
{
title = [newTitle retain];
}
}

Q. What is @synchronized in Objective C?
A. In a multithreaded environment, if more than one thread tries to access the same memory address/location, it may cause a “Race Condition”, and to avoid such kind of conditions we should use “Mutex Lock(Mutual Exclusion)” nothing but blocking or restricting or locking n number of threads to access same memory address or content at a same point of time and allowing only one thread at an instance of time. This can be achieved in Objective C by using the @synchronized directive.

or

The @synchronized directive is a convenient way to create mutex locks on the fly in Objective-C code. The @synchronized directive does what any other mutex lock does, which means it prevents different threads from acquiring the same lock at the same time.

Syntax:

@synchronized(key) 
{
// thread-safe code
}

Q. Why do we use synchronized?
A. Synchronized guarantees that only one thread can execute that code at any given time.

Q. What is retain count?
A. The number of references in the memory is the retain count. Every object has a retain count that goes up by one when the object gets a retain message and goes down by one when the object gets a release message. When the retain count reaches zero, the object calls [self dealloc] to release the object’s memory.

Q. Properties attributes?
A. These property attributes fall into three categories Atomicity(atomic, nonatomic), Access(readonly, readwrite), Storage(strong, weak, assign, copy).
Properties Default attributes are atomic, strong=retain, assign, readwrite.

atomic(default):
-
Atomic is a default attribute of property.
- An atomic property is guaranteed that if we try to read from it, we will get back a valid value. It does not make any guarantees about what that value might be, but we will get back good data, not just junk memory. What this allows us to do is if we have multiple threads or multiple processes pointing at a single variable, one thread can read and another thread can write. If they hit at the same time, the reader thread is guaranteed to get one of the two values: either before the change or after the change. What atomic does not give us is any sort of guarantee about which of those values we might get.
- Atomic is really commonly confused with being thread-safe, and that is not correct. We need to guarantee our thread safety in other ways. However, atomic will guarantee that if we try to read, we get back some kind of value.
- Thread unsafe.
- Slow in performance because atomic uses a lock and unlock process. So if there is a single threaded application, no need to set atomic because this process takes time and also uses memory.

nonatomic:
-
A nonatomic property is guaranteed that we always get back something. If we try to read in the middle of a write, we could get back garbage data.
- Thread unsafe and fast in performance.
- We use nonatomic in a single threaded or where we want that multiple threads can access the single resource at one time.

readonly: It tells the compiler not to generate a setter method automatically. If we specify readonly, only a getter method is required in the implementation block. If we attempt to assign a value using dot syntax, we get a compiler error.

readwrite(default): Default attribute again.
This indicates that property should be treated as read and write both.

strong(default):
-
Default attribute again.
- iOS 4 (non-ARC) We can use retain.
- iOS 5(ARC) We can use strong.
- By default, all instance variables and local variables are strong pointers.
- We generally use strong for UIViewControllers (UI item’s parents)
- It says “Keep this in the heap until I don’t point to it anymore.”
- Strong just means we have a reference to an object and we will keep that object alive. As long as we hold that reference to the object in that property, that object will not be deallocated and released back into memory.
- It helps, not to worry about the retain count of an object. ARC automatically release it for us when we have done with it.

retain: Old value is released and a new value is assigned.

weak: (unsafe unretained, iOS 4)
- It says “Keep this as long as someone else points to it strongly”.
- Weak gives us a reference so we can still “talk” to that object, but we are not keeping it alive. If everyone else’s strong references go away, then that object is released.
- It will just automatically nil itself out. Means If we have a reference to an object and all of the strong references to it go away and it gets deallocated.
- No retain or release means It won’t increase the reference count by one.
- We generally use weak for IBOutlets (UIViewController’s Childs). This works because the child object only needs to exist as long as the parent object does.
- It’s often used when creating a parent-child relationship. The parent has a strong reference to the child but the child only has a weak reference to the parent.

assign(default):
-
It is a default attribute and performs a variable assignment.
- No retain or release means It won’t increase the reference count by one.
- It doesn’t nil out the object when released/deallocated.
- I would use assign for C primitive properties and weak for weak references to Objective-C objects.

copy: It works really well with all kinds of mutable objects. If we set a copy property, instead of just setting both references to the same object, what it actually does is it makes a copy of the object we are setting and then sets the property to that copy. If I write in a string, it just copies that string so there are now two copies of that string. It leaves mine with me at the variable I passed in and just saves the copy. That way I can keep going with my string and I can modify it, and the one that I set remains the way that it was when I set it.

Q. What if we want one property that works as readwrite to us, but readonly to everybody else?
A. In our interface file, we would declare it as readonly, but in our implementation file, we would create a class extension and redefine it as readwrite. The keyword in the interface communicates to others that they cannot write to (a.k.a., change) the property. However, the class extension at the top of our implementation (.m) file will redefine the property with the same name, only as readwrite instead, allowing us to write to the property within the implementation file.

Q. Difference between the retain and release?
A. Retain and Release are two methods defined in the NSObject class.
These methods are related to memory management.
Retain methods when called increase the retain count by one and Release method when called decrease the retain count by one.

Q. Explain autorelease and release?
A. autorelease: By sending an object an autorelease message, It is added to the local autorelease pool and we no longer have to worry about it, because when autorelease pool is destroyed, the object will receive a release message, Its retain count will be decremented and garbage collection system will destroy the object, If the retain count is zero.
release: retain count is decremented at this point.

Q. What is the autorelease pool?
A. The Autorelease pool is like a container that holds the autorelease object. when the pool gets drained, the autorelease pool sends a release message to all the objects, it was holding.

Q. What is dealloc?
A. dealloc method of NSObject class is automatically called on an object to actually deallocate the memory for that object.
We should never call the dealloc method directly.
When the retain count of an object reaches zero, the dealloc method is called on that object automatically to delete the memory space of the object.

Q. Is delegate retained?
A. No, the delegate is never retained ever. Only CAAnimation class delegate retained. This is one of the rare exceptions.

Q. What is the memory leak?
A. If retaining and releasing are not properly used then the retain count of an object doesn’t reach zero and our application will be crash. It is called a memory leak.

Q. Difference between the shallow and deep copy?
A. In the shallow copy, we only copy the address, not actual data. In deep copy we copy data.

Q. Difference between the release and pool drain?
A. “release” frees memory and “drain” release the autorelease pool itself.

Q. What is the difference between property and instance variable?
A. A property is a more abstract concept. An instance variable is literally just a storage slot, as a slot in a struct. Normally other objects are never supposed to access them directly. Usually, a property will return or set an instance variable, but it could use data from several or none at all.

Q. What is ARC?
A. ARC is a compiler level feature that simplifies the process of managing object lifetime in the Cocoa application. In ARC compiler is responsible for the release. ARC insert appropriate memory management method at compile time.

Q. Implement the following methods: retain, release, autorelease?
A.

-(id)retain
{
NSIncrementExtraRefCount(self);
return self;
}
-(id)release
{
if(NSIncrementExtraRefCountWasZero(self))
{
NSDeallocObject(self);
}
}
-(id)autorelease
{
[NSAutoreleasePool addObject: self];
release self;
}

Q. Why do we generally create a weak reference when using self in a block/closure?
A. To avoid retain cycles and memory leaks.

Q. What is Plist?
A. Plist is a key-value store that our application use to save and retrieve persistent data.

Q. What is “id” in Objective C?
A. “id” is a generic data type. “id” is a pointer to any Objective-C object. The variable declared using id data type can hold any object.

Q. What is a collection in Objective C?
A. In Cocoa and Cocoa Touch, a collection is a Foundation framework class used for storing and managing groups of objects. Its primary role is to store objects in the form of either an array, a dictionary, or a set. The collection classes use strong references to keep track of their contents.

All collections share a number of common tasks, which include:
- Enumerating the objects in a collection
- Determining whether an object is in a collection
- Accessing individual elements in a collection

Mutable collections also allow some additional tasks:
- Adding objects to a collection
- Removing objects from a collection

Q. Types of collections in Objective C?
A. Array, Dictionary, Set

Q. Difference between the “Synchronous” and “Asynchronous” Call?
A. Synchronous means ‘ordered communication’. Asynchronous means ‘unordered communication.
Synchronous means that we trigger our request and wait for it to be done. Asynchronous means that we trigger the request and do other stuff while NSURLConnection download data.
Synchronous waits until the task has completed. Asynchronous completes a task in the background and can notify us when complete.

Q. What is Fast Enumeration?
A. Fast enumeration is a language feature that allows us to enumerate over the contents of a collection. By using this feature our code also runs faster because the internal implementation reduces message send overhead and increases pipelining potentials.

Q. Difference between Immutable and Mutable in Objective C?
A. An immutable object can’t be changed but we can change the value of a mutable object.

Q. Difference between NSArray and NSMutableArray in Objective C?
A. NSArray’s(Immutable) content can’t be modified once it has been created whereas NSMutableArray(Mutable) can be modified as needed i.e. items can be added or removed from it at runtime.

Q. Difference between the array in Objective C and array in C?
A. Array in C is the homogenous type and Array in Objective C is the heterogeneous type.

Q. Difference between the NSArray and NSSet in Objective C?
A. NSArray — id type and indexing. Arrays Are Ordered Collections.
NSSet — id type and no indexing. Sets Are Unordered Collections.

Q. Difference between the NSNumber and NSInt?
A. NSNumber: Can hold an int, double, float, char, string, hexadecimal, etc.
NSInt: Can hold only an integer value.

Q. Which is faster for a search, an NSArray, or an NSSet?
A. When the order of the items in the collection is not important, NSSet offers better performance for finding items in the collection; the reason is that the NSSet uses hash values to find items (like a dictionary), while an array has to iterate over its entire contents to find a particular object.

Q. -Objc linker flag?
A.
-ObjC Loads all members of static archive libraries that implement an Objective-C class or category.

Q. -all_load or -force_load linker flag?
A.
For 64-bit and iPhone OS applications, there is a linker bug that prevents -ObjC from loading objects files from static archive libraries that contain only categories and no classes. The workaround is to use the -all_load or -force_load flags. -all_load forces the linker to load all object files from every archive it sees, even those without Objective-C code. -force_load is available in Xcode 3.2 and later. It allows finer grain control of archive loading. Each -force_load option must be followed by a path to an archive, and every object file in that archive will be loaded.

Thank you for reading! If you liked this article, please clap to get this article seen by more people.
Please follow me on Medium by clicking Follow.
I’m also active on LinkedIn, Twitter, and GitHub.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store