iOS Interview Questions and Answers
Practice iOS interview questions and answers organized by difficulty, with revealable explanations and related topics.
Junior questions
6 questions- Question 1Junior
What is CoreData?
- iOS
Reveal answerHide answer
Core Data is an object graph management framework. It manages a potentially very large graph of object instances, allowing an app to work with a graph that would not entirely fit into memory by faulting objects in and out of memory as necessary. Core Data also manages constraints on properties and relationships and maintains reference integrity (e.g. keeping forward and backward links consistent when objects are added/removed to/from a relationship). Core Data is thus an ideal framework for building the "model" component of an MVC architecture. To implement its graph management, Core Data happens to use SQLite as a disk store. It could have been implemented using a different relational database or even a non-relational database such as CouchDB. Core Data isn't so much a database engine as it is an API that abstracts over the actual data store. You can tell Core Data to save as an sqlite database, a plist, a binary file, or even a custom data store type.
- Question 2Junior
What are different ways that you can specify the layout of elements in a UIView ?
- iOS
Reveal answerHide answer
Here are a few common ways to specify the layout of elements in a UIView : Using InterfaceBuilder, you can add a XIB file to your project, layout elements within it, and then load the XIB in your application code (either automatically, based on naming conventions, or manually). Also, using InterfaceBuilder you can create a storyboard for your application. You can your own code to use NSLayoutConstraints to have elements in a view arranged by Auto Layout. You can create CGRect s describing the exact coordinates for each element and pass them to UIView ’s - (id)initWithFrame:(CGRect)frame method.
- Question 3Junior
What's your preference when writing UI's? Xib files, Storyboards or programmatic UIView ?
- iOS
Reveal answerHide answer
Storyboard's and Xib's are great for quickly producing UI's that match a design spec. They are also really easy for product managers to visually see how far along a screen is. Storyboard's are also great at representing a flow through an application and allowing a high-level visualization of an entire application.
Storyboard's drawbacks are that in a team environment they are difficult to work on collaboratively because they're a single file and merge's become difficult to manage. Storyboards and Xib files can also suffer from duplication and become difficult to update. For example if all button's need to look identical and suddenly need a color change, then it can be a long/difficult process to do this across storyboards and xibs. Programmatically constructing UIView 's can be verbose and tedious, but it can allow for greater control and also easier separation and sharing of code. They can also be more easily unit tested. Most developers will propose a combination of all 3 where it makes sense to share code, then re-usable UIView s or Xib files.
- Question 4Junior
What is the difference between viewDidLoad and viewDidAppear ?
- iOS
Reveal answerHide answer
viewDidLoad is called when the view is loaded, 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 your 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.
- Question 5Junior
What is CoreData?
- iOS
Reveal answerHide answer
Core Data is an object graph management framework. It manages a potentially very large graph of object instances, allowing an app to work with a graph that would not entirely fit into memory by faulting objects in and out of memory as necessary. Core Data also manages constraints on properties and relationships and maintains reference integrity (e.g. keeping forward and backward links consistent when objects are added/removed to/from a relationship). Core Data is thus an ideal framework for building the "model" component of an MVC architecture. To implement its graph management, Core Data happens to use SQLite as a disk store. It could have been implemented using a different relational database or even a non-relational database such as CouchDB. Core Data isn't so much a database engine as it is an API that abstracts over the actual data store. You can tell Core Data to save as an sqlite database, a plist, a binary file, or even a custom data store type.
- Question 6Junior
Explain what is NSUserDefaults ?
- iOS
Reveal answerHide answer
NSUserDefaults is the easiest way to store data without a database using key-value pair. This approach is the ideal way to store small amounts of data. In most cases, NSUserDefaults is best used to save user’s settings and data that is not critical. The following types are supported by NSUserDefaults: NSString NSNumber NSDate
NSDictionary NSData Pros Relatively easy to store and retrieve data Perfect for storing small size data (example: User’s Settings) Easy to learn and implement Cons Not ideal to store large amount of data Performance will decrease when storing large amount of data Not ideal to store sensitive data
Mid questions
16 questions- Question 1Mid
What options do you have for implementing storage and persistence on iOS?
- iOS
Reveal answerHide answer
Generally there are the following ways to store data in order from simple to complex: In-memory arrays, dictionaries, sets, and other data structures are perfectly fine for storing data intermediately or if it doesn’t have to be persisted. NSUserDefaults/Keychain are simple key-value stores. One is insecure and the other is secure, respectively. File/disk storage is a way of writing data (serialized or not) to/from a disk using NSFileManager. Core Data and Realm are frameworks that simplify work with databases. SQLite is a relational database and is good when you need to implement complex querying mechanics and Core Data or Realm won’t cut it.
- Question 2Mid
What is the Responder Chain?
- iOS
Reveal answerHide answer
When an event happens in a view, for example a touch event, the view will fire the event to a chain of UIResponder objects associated with the UIView . The first UIResponder is the UIView itself, if it does not handle the event then it continues up the chain to until UIResponder handles the event. The chain will include UIViewController s, parent UIView s and their associated UIViewController s, if none of those handle the event then the UIWindow is asked if it can handle it and finally if that doesn't handle the event then the UIApplicationDelegate is asked. Consider:
- Question 2Mid
What are the options for laying out UI on iOS?
- iOS
Reveal answerHide answer
Since iOS 6 we have AutoLayout, which is the go-to solution these days and which Apple prefers. AutoLayout is a technology that helps you define relationships between views, called constraints, in a declarative way, letting the framework calculate precise frames and positions of UI elements instead. With iOS 13, Apple introduced a new approach for laying out views - SwiftUI, which is a declarative approach that supports FRP (functional-reactive programming) data bindings with Combine. FRP and declarative UI are not new concepts, but SwiftUI and Combine are new frameworks from Apple that support it. The declarative nature of SwiftUI allows you to declare your UI elements very concisely and then later through data bindings declare what parts of the UI, such as text labels for example, to update upon what data model changes. In effect, it allows you to do what was already possible with RxSwift before, but now with Apple frameworks. There are other options for laying out views, such as ASDK (Texture), ComponentKit, and LayoutKit, and some of them are more or less inspired by React and others solve layout Asynchronicity differently. These alternatives are good in certain scenarios when, for example, you need to build highly dynamic and fast table views and collection views. AutoLayout is not always perfect for that and knowing there are other options is always good.
- Question 7Mid
Explain iOS App States
- iOS
Reveal answerHide answer
Every iOS app is always in one of the five app states. The operating system manages the app state, but the app itself is responsible for managing important tasks to ensure smooth transitions between the states. The five states of an iOS app - as listed in the iOS App Programming Guide - include the following: 1. Non-running - The app is not running. 2. Inactive - The app is running in the foreground, but not receiving events. An iOS app can be placed into an inactive state, for example, when a call or SMS message is received. 3. Active - The app is running in the foreground, and receiving events. 4. Background - The app is running in the background, and executing code. 5. Suspended - The app is in the background, but no code is being executed.
- Question 8Mid
Explain the difference between Background vs Suspended app state
- iOS
Reveal answerHide answer
Background: Executing code - Code is executed while the app is in a background state. An app must go into a background state before it can go into a suspended state. ie. Suppose you're on Facebook and you upload a video and you quickly switch to another app immediately after pressing the POST button. Although you switched to another app w/o terminating the app, the app can be configured to perform background processes to complete the upload. An app that is in background does not necessarily mean it is suspended but an app that is suspended is in background. An app can request to stay in background mode for extra time (for purposes of playing audio in the background or completing a network request, for example); afterward it will either go to suspended state or it will be forcibly terminated by the system. Suspended: Not executing code - Code is not executed while the app is in a suspended state.
An app that is in a suspended state is also in a background state. The system moves apps to this state w/o notifying you beforehand. An app in a suspended state is still in memory.
- Question 9Mid
What's the difference between the frame and the bounds ?
- iOS
Reveal answerHide answer
frame = a view's location and size using the parent view's coordinate system Important for: placing the view in the parent To help me remember frame, I think of a picture frame on a wall. The picture frame is like the border of a view. bounds = a view's location and size using its own coordinate system Important for: placing the view's content or subviews within itself To help me remember bounds, I think of a basketball court where sometimes the basketball gets knocked out of bounds.
- Question 10Mid
Explain code signing for iOS apps
- iOS
Reveal answerHide answer
Signing an application allows the system to identify who signed the application and to verify that the application has not been modi ed since it was signed. Signing is a requirement for submitting to the App Store (both for iOS and Mac apps). OS X and iOS verify the signature of applications downloaded from the App Store to ensure that they they do not run applications with invalid signatures. This lets users trust that the application was signed by an Apple source and hasn’t been modifed since it was signed. Xcode uses your digital identity to sign your application during the build process. This digital identity consists of a public-private key pair and a certificate. The private key is used by cryptographic functions to generate the signature. The certificate is issued by Apple; it contains the public key and identifies you as the owner of the key pair. An application’s executable code is protected by its signature because the signature becomes invalid if any of the executable code in the application bundle changes. Resources such as images and nib files are not signed; a change to these files does not invalidate the signature. An application’s signature can be removed, and the application can be re-signed using another digital identity. For example, Apple re-signs all applications sold on the App Store. Also, a fully- tested development build of your application can be re-signed for submission to the App Store. Thus the signature is best understood not as indelible proof of the application’s origins but as a variable mark placed by the signer.
- Question 12Mid
Explain when to use various storage mechanisms in iOS?
- iOS
Reveal answerHide answer
NSUserDefaults : stores simple user preferences, nothing too complex or secure. If your app has a setting page with a few switches, you could save the data here. Keychain (see SSKeychain for a great wrapper): used to store sensitive data, like credentials. PLists : used to store larger structured data (but not huge): it is a really flexible format and can be used in a great number of scenarios. Some examples are: User generated content storage: a simple list of Geopoint that will be shown by a map or list. Provide simple initial data to your app: in this case the plist will be included in the NSBundle, instead of being generated by user and filled by user data. Separate the data needed for a particular module of your application from other data. For example, the data needed to build a step-by-step startup tutorial, where each step is similar to the others but just needs different data. Hard-coding this data would easily fill your code, so you could be a better developer and use plists to store the data and read from them instead.
You are writing a library or framework that could be configured in some way by the developer that uses it. Object archiving could be useful to serialize more complex objects, maybe full of binary data, that can't (or that you don't want to) be mapped on simpler structures like plists. Core Data is powerful, can be backed by different persistent stores (SQLite is just one of them, but you can also choose XML files or you can even write your own format!), and gives relationships between elements. It is complex and provides many features useful for the development, like KVO and contexts. You should use it for large data sets of many correlated records, that could be user generated or provided by a server. Raw SQLite is useful when you need really, really fast access to a relational data source (Core Data introduces some overhead), or if you need to support the same SQLite format across multiple platforms (you should never mess with CoreData inner SQLite: it uses its own format, so you can't just "import" an existing SQLite in CoreData). For example, for a project I worked for, a webservice provided me some large SQLite instead of jsons or xmls: some of this SQLite were imported to CoreData (operation that could take a while, depending on the source size), because I needed all the features of it, while other SQLites were read directly for a really fast access. Webserver storage well it should be obvious: if you need to store data to a server it is because the device shouldn't be the only owner of that data. But if you just need to synchronize the same App across different iOS devices (or even with a Mac-ported version of the App) you could also look at iCloud storage, obviously.
- Question 13Mid
What considerations do you need when writing a UITableViewController which shows images downloaded from a remote server?
- iOS
Reveal answerHide answer
The images are hosted remotely and they may take time to download, therefore: Only download the image when the cell is scrolled into view, i.e. when cellForRowAtIndexPath is called. Downloading the image asynchronously on a background thread so as not to block the UI so the user can keep scrolling. When the image has downloaded for a cell we need to check if that cell is still in the view or whether it has been re-used by another piece of data. If it’s been re-used then we should discard the image, otherwise we need to switch back to the main thread to change the image on the cell.
- Question 14Mid
What mechanisms does iOS provide to support multi- threading?
- iOS Objective-C
Reveal answerHide answer
NSThread creates a new low-level thread which can be started by calling the start method. NSThread* myThread = [[NSThread alloc] initWithTarget:self
selector:@selector(myThreadMainMethod:) object:nil]; [myThread start];NSOperationQueue allows a pool of threads to be created and used to execute NSOperation s in parallel. NSOperation s can also be run on the main thread by asking NSOperationQueue for the mainQueue .
NSOperationQueue* myQueue = [[NSOperationQueue alloc] init]; [myQueue addOperation:anOperation]; [myQueue addOperationWithBlock:^{ /* Do something. */ }];GCD or Grand Central Dispatch is a modern feature of Objective-C that provides a rich set of methods and API's to use in order to support common multi-threading tasks. GCD provides a way to queue tasks for dispatch on either the main thread, a concurrent queue (tasks are run in parallel) or a serial queue (tasks are run in FIFO order). dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(myQueue, ^{ printf("Do some work here.\n"); }); - Question 15Mid
What is the Responder Chain?
- iOS
Reveal answerHide answer
When an event happens in a view, for example a touch event, the view will fire the event to a chain of UIResponder objects associated with the UIView . The first UIResponder is the UIView itself, if it does not handle the event then it continues up the chain to until UIResponder handles the event. The chain will include UIViewController s, parent UIView s and their associated UIViewController s, if none of those handle the event then the UIWindow is asked if it can handle it and finally if that doesn't handle the event then the UIApplicationDelegate is asked. Consider:
- Question 16Mid
What are some pros and cons of Core Data?
- iOS
Reveal answerHide answer
Pros of CoreData: Reliable framework to interact and query against data Can be extremely fast when setup correctly (with relationships) Powerful capabilities Cons of CoreData Takes time to master and learn the core concept Needs proper app architecture design to be efficient You cannot have a learn and implement in a day approach with CoreData As you improve your app, you need to improve your data architecture as well Migrating to new versions can be a pain if you are not careful.
- Question 17Mid
What is AutoLayout? What does it mean when a constraint isbroken by iOS?
- iOS
Reveal answerHide answer
AutoLayout is way of laying out UIView s using a set of constraints that specify the location and size based relative to other views or based on explicit values. AutoLayout makes it easier to design screens that resize and layout out their components better based on the size and orientation of a screen. Constraints include: setting the horizontal/vertical distance between 2 views setting the height/width to be a ratio relative to a different view a width/height/spacing can be an explicit static value Sometimes constraints conflict with each other. For example imagine a UIView which has 2 height constraints: one says make the UIView 200px high, and the second says make the height twice the height of a button. If the iOS runtime can not satisfy both of these constraints then it has to pick only one. The other is then reported as being broken by iOS.
- Question 18Mid
What’s the difference between an app ID and a bundle ID and what is each used for?
- iOS
Reveal answerHide answer
An App ID is a two-part string used to identify one or more apps from a single development team. The string consists of a Team ID and a bundle ID search string, with a period (.) separating the two parts. The Team ID is supplied by Apple and is unique to a specific development team, while the bundle ID search string is supplied by teh developer to match either the bundle ID of a single app or a set of bundle IDs for a group of apps. Because most people think of the App ID as a string, they think it is interchangeable with Bundle ID. It appears this way because once the App ID is created in the Member Center, you only ever use the App ID Prefix which matches the Bundle ID of the Application Bundle. The bundle ID uniquely defines each App. It is specified in Xcode. A single Xcode project can have multiple Targets and therefore output multiple apps. A common use case for this is an app that has both lite/free and pro/full versions or is branded multiple ways.
- Question 19Mid
Explain View Controller Lifecycle events and their order
- iOS
Reveal answerHide answer
There are a few different lifecycle events
- loadView Creates the view that the controller manages. It’s only called when the view controller is created and only when done programatically. It is responsible for making the view property exist in the first place.
- viewDidLoad Called after the controller’s view is loaded into memory. It’s only called when the view is created.
- viewWillAppear It’s called whenever the view is presented on the screen. In this step the view has bounds defined but the orientation is not applied.
- viewWillLayoutSubviews Called to notify the view controller that its view is about to layout its subviews. This method is called every time the frame changes
- viewDidLayoutSubviews Called to notify the view controller that its view has just laid out its subviews. Make additional changes here after the view lays out its subviews.
- viewDidAppear Notifies the view controller that its view was added to a view hierarchy.
- viewWillDisappear Before the transition to the next view controller happens and the origin view controller gets removed from screen, this method gets called.
- viewDidDisappear After a view controller gets removed from the screen, this method gets called. You usually override this method to stop tasks that are should not run while a view controller is not on screen.
- 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.
- Question 20Mid
When would you use Core Data over NSUserDefault ?
- iOS
Reveal answerHide answer
NSUserDefaults as the name suggests (vaguely) should be used for storing preferences and app settings only. You should not be storing critical data and or user data into them. Use UserDefaults in small projects or to store some flags. Don't use UserDefaults to store big data, such as image caching. CoreData is a full fledged persistent framework which supports large data transactions. CoreData allows you to build relational entity–attribute model for storing user data. Use CoreData in big projects. CoreData entities are generally a better design than arbitrary values stored by keys, even if later serialized to objects.
Senior questions
8 questions- Question 3Senior
What is the difference between ARC (automatic reference counting) and GC (garbage collection)?
- Objective-C iOS Swift
Reveal answerHide answer
ARC rely on a compile time "referenced" objects which make it efficient in a low-power mode environments (Mobile devices).
ARC injects a code into the executable to be executed "automatically" on unused objects depending on their reference count. Advantages: Real-time, deterministic destruction of objects as they become unused. No background processing. Disadvantages: ARC cannot handle retain cycles automatically. GC rely on a runtime based "reachable" objects which make it efficient in a multi-threaded environment. GC works in the runtime as it will detect the unused object graphs (will eliminate retain-cycles) and remove them on an indeterminate time intervals Advantages: GC can clean up entire object graphs, including retain cycles. GC proceed in the background, so less memory management work is done as part of the regular application flow. Disadvantages: Because GC happens in the background, the exact time frame for object releases is undetermined. When a GC happens, other threads in the application may be temporarily put on hold.
- Question 4Senior
What is @autoreleasepool ?
- Objective-C iOS
Reveal answerHide answer
The concept of an autorelease pool is simple, whenever an object instance is marked as autoreleased (for example NSString* str = [[[NSString alloc] initWithString:@"hello"] autorelease]; ), it will have a retain count of +1 at that moment in time, but at the end of the run loop, the pool is drained, and any object marked autorelease then has its retain count decremented. It's a way of keeping an object around while you prepare whatever will retain it for itself. With ARC, whilst the autorelease keyword isn't used by the developer, the underlying system that manages ARC inserts that for you. (Remember: All ARC is doing is inserting retain , release and autorelease calls for you at the appropriate times). Because of this, the existing AutoreleasePool concept needs to stay around.
- Question 5Senior
What are the reasons for using NSOperationQueue over GCD and vice versa?
- Objective-C iOS
Reveal answerHide answer
GCD is a low-level C-based API. NSOperation and NSOperationQueue are Objective-C classes. NSOperationQueue is objective C wrapper over GCD . If you are using NSOperation, then you are implicitly using Grand Central Dispatch. GCD advantage over NSOperation : i. implementation For GCD implementation is very light-weight NSOperationQueue is complex and heavy-weight NSOperation advantages over GCD:
i. Control On Operation you can Pause, Cancel, Resume an NSOperation ii. Dependencies you can set up a dependency between two NSOperations operation will not started until all of its dependencies return true for finished. iii. State of Operation can monitor the state of an operation or operation queue. ready ,executing or finished iv. Max Number of Operation you can specify the maximum number of queued operations that can run simultaneously When to Go for GCD or NSOperation When you want more control over queue (all above mentioned) use NSOperation For simple cases where you want less overhead (you just want to do some work "into the background" with very little additional work) use GCD
- Question 6Senior
What is QoS (Quality of Service) in GCD?
- Swift iOS
Reveal answerHide answer
Defining quality of service helps us categorize the task of our DispatchQueue with priority. By using it the right way, we could make our app energy efficient and responsive. QoS can be used with .async() function, and the priorities are divided into four main categories. userInteractive: Used for animations, or updating UI. userInitiated: Used for tasks like loading data from API, preventing the user from making interactions. utility: Used for tasks that do not need to be tracked by the user. background: Used for tasks like saving data in the local database or any maintenance code which is not on high priority. Consider:
let queue = DispatchQueue(label: "com.swiftpal.dispatch.qos")// async with background type queue.async(qos: .background) { print("Background Code") }// async with userInitiated type queue.async(qos: .userInitiated) { print("User Initiated Code") } - Question 7Senior
Explain how an autorelease pool works at the runtime level
- iOS
Reveal answerHide answer
Autorelease pool blocks provide a mechanism whereby you can relinquish ownership of an object, but avoid the possibility of it being deallocated immediately (such as when you return an object from a method). Typically, you don’t need to create your own autorelease pool blocks, but there are some situations in which either you must or it is beneficial to do so. There are, however, three occasions when you might use your own autorelease pool blocks:
- If you are writing a program that is not based on a UI framework, such as a command-line tool.
- If you write a loop that creates many temporary objects. You may use an autorelease pool block inside the loop to dispose of those objects before the next iteration. Using an autorelease pool block in the loop helps to reduce the maximum memory footprint of the application.
- If you spawn a secondary thread. You must create your own autorelease pool block as soon as the thread begins executing; otherwise, your application will leak objects.
- Question 8Senior
What's the difference between using a delegate andnotification?
- iOS Objective-C
Reveal answerHide answer
Both are used for sending values and messages to interested parties. A Delegate is for one-to-one communication and is a pattern promoted by Apple. In delegation the class raising events will have a property for the delegate and will typically expect it to implement some protocol . The delegating class can then call the delegates protocol methods. Notification allows a class to broadcast events across the entire application to any interested parties. The broadcasting class doesn't need to know anything about the listeners for this event, therefore notification is very useful in helping to decouple components in an application.
[NSNotificationCenter defaultCenter] postNotificationName:@"TestNotification" object:self]; - Question 9Senior
Describe managed object context and the functionality that it provides
- iOS
Reveal answerHide answer
A managed object context (represented by an instance of NSManagedObjectContext ) is basically a temporary “scratch pad” in an application for a (presumably) related collection of objects. These objects collectively represent an internally consistent view of one or more persistent stores. A single managed object instance exists in one and only one context, but multiple copies of an object can exist in different contexts. You can think of a managed object context as an intelligent scratch pad. When you fetch objects from a persistent store, you bring temporary copies onto the scratch pad where they form an object graph (or a collection of object graphs). You can then modify those objects however you like. Unless you actually save those changes, though, the persistent store remains unchanged. Key functionality provided by a managed object context includes: Life-cycle management. The context provides validation, inverse relationship handling, and undo/redo. Through a context you can retrieve or “fetch” objects from a persistent store, make changes to those objects,
and then either discard the changes or commit them back to the persistent store. The context is responsible for watching for changes in its objects and maintains an undo manager so you can have finer-grained control over undo and redo. You can insert new objects and delete ones you have fetched, and commit these modifications to the persistent store. Notifications. A context posts notifications at various points which can optionally be monitored elsewhere in your application. Concurrency. Core Data uses thread (or serialized queue) confinement to protect managed objects and managed object contexts. In OS X v10.7 and later and iOS v5.0 and later, when you create a context you can specify the concurrency pattern with which you will use it using initWithConcurrencyType: .
- Question 10Senior
What are the most important application delegate methods?
- iOS
Reveal answerHide answer
The operating system calls specific methods within the application delegate to facilitate transitioning to and from various states. The seven most important application delegate methods a developer should handle are: application:willFinishLaunchingWithOptions Method called when the launch process is initiated. This is the first opportunity to execute any code within the app.
* application:didFinishLaunchingWithOptionsMethod called when the launch process is nearly complete. Since this method is called is before any of the app’s windows are displayed, it is the last opportunity to prepare the interface and make any final adjustments.
* applicationDidBecomeActiveOnce the application has become active, the application delegate will receive a callback notification message via the method applicationDidBecomeActive . This method is also called each time the app returns to an active state from a previous switch to inactive from a resulting phone call or SMS. applicationWillResignActive There are several conditions that will spawn the applicationWillResignActive method. Each time a temporary event, such as a phone call, happens this method gets called. It is also important to note that “quitting” an iOS app does not terminate the processes, but rather moves the app to the background. applicationDidEnterBackground
This method is called when an iOS app is running, but no longer in the foreground. In other words, the user interface is not currently being displayed. According to Apple’s UIApplicationDelegate Protocol Reference, the app has approximately five seconds to perform tasks and return. If the method does not return within five seconds, the application is terminated.
* applicationWillEnterForegroundThis method is called as an app is preparing to move from the background to the foreground. The app, however, is not moved into an active state without the applicationDidBecomeActive method being called. This method gives a developer the opportunity to re-establish the settings of the previous running state before the app becomes active.
* applicationWillTerminateThis method notifies your application delegate when a termination event has been triggered. Hitting the home button no longer quits the application. Force quitting the iOS app, or shutting down the device triggers the applicationWillTerminate method. This is an opportunity to save the application configuration, settings, and user preferences. Two more delegate functions come with iOS13: configurationForConnecting According to Apple, it returns the configuration data for UIKit to use when creating a new scene.
* didDiscardSceneSessionsThis method is called as an app’s user closed one or more scenes via the app switcher.
Expert questions
6 questions- Question 11Expert
Explain the use case when ARC won't help you to release memory (but GC will)?
- Objective-C iOS Swift
Reveal answerHide answer
As an example, if you have a class named node, and node has an NSArray of children, and a single reference to its parent that "just works" with GC. With ARC (and manual reference counting as well) you have a problem. Any given node will be referenced from its children and also from its parent. Like:
A -> [B1, B2, B3] B1 -> A, B2 -> A, B3 -> A All is fine while you are using A (say via a local variable).When you are done with it (and B1/B2/B3), a GC system will eventually decide to look at everything it can find starting from the stack and CPU registers. It will never find A,B1,B2,B3 so it will finalize them and recycle the memory into other objects. When you use ARC or MRC, and finish with A it have a refcount of 3 (B1, B2, and B3 all reference it), and B1/B2/B3 will all have a reference count of 1 (A's NSArray holds one reference to each). So all of those objects remain live even though nothing can ever use them. The common solution is to decide one of those references needs to be weak (not contribute to the reference count). That will work for some usage patterns, for example if you reference B1/B2/B3 only via A. However in other patterns it fails. For example if you will sometimes hold onto B1, and expect to climb back up via the parent pointer and find A. With a weak reference if you only hold onto B1, A can (and normally will) evaporate, and take B2, and B3 with it. You can also say ARC puts a bigger priority on performance (or maybe predictability) while GC puts a bigger priority on being a generic solution. As a result GC has less predictable CPU/memory demands, and a lower
performance (normally) than ARC, but can handle any usage pattern. ARC will work much better for many many common usage patterns, but for a few (valid!) usage patterns it will fall over and die. - Question 12Expert
What iOS architectures do you know that scale?
- iOS
Reveal answerHide answer
Clean Architecture is a conceptual application architecture for scale and can be simply described as “an onion layered architecture”. The main idea is to keep dependencies pointing inward towards your domain logic and domain models and keeping everything else pluggable and optional (the way you store data, render ui, receive or send networking requests, etc.). This architecture scales particularly well for large teams of 100+ developers. There are two concrete implementations of Clean Architecture on iOS: VIPER and RIBs. VIPER stands for View, Interactor, Presenter, Entity, and Router. Those are the building blocks of that architecture. In this architecture, everything starts with a router and ends with a view. Each VIPER stack (meaning a set of a View, Interactor, Presenter, Entity, and Router) is one screen or one logical UI part of your application. To navigate and use a VIPER stack, you'd instantiate its router and then ask it to create its view controller. The router creates a view controller, a corresponding presenter that formats data for the view and receives user input for the view, an interactor that holds business logic and communicates with presenter, and entities necessary for interactor to work. Then the VC owns presenter, presenter owns interactor, and interactor owns entities and the router. The resulting view controller is used in your view hierarchy and inserted, pushed, or presented as necessary. This architecture allows for strong encapsulation of logic and scalability for team size since every part of your app is now a VIPER stack. RIBs stands for Router, Interactor, Builder. RIBs is another implementation of Clean Architecture that was an improvement on VIPER. In RIBs architecture, the main building block is a RIB, a set of one router, one interactor, and one builder with optional view and presenter. RIBs without a view are called headless RIBs. Just like in VIPER architecture, you route from one RIB to another using router, and that structures the entire runtime of your app in as a tree structure with parent and children RIBs. Since the view is optional, unlike with VIPER, your application tree structure might or might not mimic your view hierarchy.
- Question 13Expert
Why and in which conditions should we use @autoreleasepool ?
- Objective-C iOS
Reveal answerHide answer
When you can ensure a specific thread is never making use of autoreleased objects, that thread wouldn't need an autorelease pool. Avoiding the autoreleasepool is a bad advice, the coin has two sides. Using autorelease'd objects carries a certain amount of overhead (although insignificant in most scenarios) that should be avoided when possible. Especially in cases where there are multiple exits to a method, or an exception can be encountered, autoreleasing helps avoiding memory leaks and makes code cleaner. Be aware though, that this means nothing on that thread can use autorelease, including any frameworks you may call. There are situations where this is the case, such as in a classic producer/consumer scenario. You have a producer that creates objects, dispatches them to the main threads runloop, and can register them in the main threads autoreleasepool consequently. In general, I would not recommend creating a thread where significant work is carried out (besides a simple, long running computation) without an autoreleasepool.
- Question 14Expert
Which is the best of GCD, NSThread or NSOperationQueue ?
- Objective-C iOS
Reveal answerHide answer
- Use NSThread (or even the pthreads API) when you want or need to have_ direct control over the threads you create_, e.g. you need fine-grained control over thread priorities or are interfacing with some other subsystem that vends/consumes thread objects directly and you need to stay on the same page with it. Such instances are rare, but they do occur, particularly in real-time applications.
- Use GCD when your task lends itself well to simple parallelization, e.g. you just want to toss some work "into the background" with very little additional work, you have some data structures that you merely wish to serialize access to (and serial queues are great for doing that in a lockless fashion), you have some for loops that would lend themselves well to parallelization with dispatch_apply(), you have some data sources / timers that GCD's sources API will enable you to deal with easily in the background, etc etc. GCD is quite powerful and you can use it for a lot more than this, but these are all relative 'no brainer' scenarios where you don't want to get caught up in the initialization and setup tasks so much as simply "do basic stuff in parallel".
- Use NSOperation when you're already up at the Cocoa API layer (vs writing in straight C to the POSIX APIs) and have more complex operations you want to parallelize. NSOperation allows for subclassing, arbitrarily complex dependency graphs, cancellation and a supports a number of other higher-level semantics that may be useful to you. NSOperation actually uses GCD under the covers so it's every bit as multi-core, multi-thread capable as GCD, though it also brings the Foundation framework along for the ride so if you're hacking at the POSIX layer, you probably want to use option #2.
- Question 15Expert
What are the benefits of using DispatchWorkItem in Swift?
- Swift iOS
Reveal answerHide answer
The DispatchWorkItem class is an encapsulation of the concept of work item. By encapsulating our request code in a work item, we can very easily cancel it whenever it's replaced by a new one, like this:
class SearchViewController: UIViewController, UISearchBarDelegate { // We keep track of the pending work item as a property private var pendingRequestWorkItem: DispatchWorkItem? func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { // Cancel the currently pending item pendingRequestWorkItem?.cancel() // Wrap our request in a work item let requestWorkItem = DispatchWorkItem { [weak self] in self?.resultsLoader.loadResults(forQuery: searchText) } // Save the new work item and execute it after 250 ms pendingRequestWorkItem = requestWorkItem DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(250), execute: requestWorkItem) } } - Question 16Expert
Explain usage of Concurrent vs Serial Queues with async and sync blocks
- iOS Swift
Reveal answerHide answer
- the queue's type ( Concurrent or Serial) is the ONLY element that decides whether the tasks are executed in order or in paralel;
- the dispatch type ( sync or async ) is only saying whether the execution goes OR doesn't go to the next instruction The queue dictates the execution policy, not how you queue the block. sync waits for the block to complete, async doesn't. A simple example: you have a block that takes a minute to execute. You add it to a queue from the main thread. Let's look at the four cases. async - concurrent: the code runs on a background thread. Control returns immediately to the main thread (and UI). The block can't assume that it's the only block running on that queue async - serial: the code runs on a background thread. Control returns immediately to the main thread. The block can assume that it's the only block running on that queue sync - concurrent: the code runs on a background thread but the main thread waits for it to finish, blocking any updates to the UI. The block can't assume that it's the only block running on that queue (I could have added another block using async a few seconds previously) sync - serial: the code runs on a background thread but the main thread waits for it to finish, blocking any updates to the UI. The block can assume that it's the only block running on that queue