The Top 25 NSString Interview Questions for iOS Developers in 2023

As an iOS developer, having a strong grasp of NSString is vital for success in technical interviews and day-to-day work. NSString, a key Foundation framework class, provides immutable Unicode-compliant strings used ubiquitously in iOS and macOS programming.

In this comprehensive guide, I’ll share the top 25 NSString interview questions frequently asked of iOS developers Mastering these questions demonstrates your proficiency with string manipulation and immutability in Objective-C

Whether you’re prepping for an upcoming interview or looking to deepen your NSString knowledge, this article has you covered. Let’s dive in!

1. What’s the Difference Between NSString and NSMutableString?

This is one of the most common NSString interview questions.

The key distinction is mutability. NSString is immutable – once created, its value can’t be changed. This makes it thread-safe.

NSMutableString is mutable, allowing modifications like appendString: and insertString:atIndex:. However, this flexibility comes at the cost of thread-safety.

When frequent changes are needed, NSMutableString boosts efficiency by avoiding new string creation. But immutable NSString shines for thread-safety.

2. How Do You Convert Between NSString and NSData?

Interviewers often ask how to convert between string and binary data representations.

To make an NSString into NSData, use dataUsingEncoding to get a data object encoded in a specified format like UTF-8.

Conversely, initializing an NSString with NSData requires initWithData:encoding: to interpret the data as a string per the encoding.

3. How Do You Concatenate Two NSString Instances?

When building strings, concatenation is indispensable.

The go-to method is stringByAppendingString – this appends one string to another, returning a new combined string.

For example, @"Hello" stringByAppendingString:@" World!" results in @"Hello World!".

4. What is Unicode and How Does NSString Utilize It?

As iOS development uses Unicode extensively, this relationship merits understanding.

Unicode provides a universal character set covering all writing systems. This enables consistent text representation across platforms and languages.

NSString uses Unicode for its internal string representation. This allows it to contain any valid Unicode while ensuring fidelity. NSString also provides conversions from other encodings to Unicode.

5. How Do You Convert Between NSString and NSNumber?

Bridging between strings and numbers is commonplace.

To make an NSString into NSNumber, use an NSNumberFormatter and its numberFromString: method.

Going the other way, NSNumber to NSString uses stringFromNumber: on the formatter.

This handles parsing the number into a string representation.

6. What’s the Difference Between String Literals and NSString?

While both deal with text, string literals and NSString have key differences interviewers look for.

String literals are compile-time sequences in double quotes. They are immutable but not objects.

NSString is a full-fledged class, allowing mutability and offering methods for manipulation. Literals must be converted to NSString for operations.

7. How Do You Get an NSString’s Length?

When working with strings, we often need to know their length.

The length property provides this. It returns the string’s length as an NSUInteger – the count of Unicode characters.

Accessing it is straightforward: myString.length

8. How Are NSStrings Compared for Equality?

Checking strings for equality is common. The technique differs from other objects.

To compare NSString values, use isEqualToString:. This evaluates string contents, not pointer identity.

string1.isEqualToString(string2) will be YES if the strings contain the same text. Case-sensitivity applies.

9. How Do You Convert Between NSString and C Strings?

Interoperating with C requires string conversion.

UTF8String converts an NSString to a C string. This provides a null-terminated UTF-8 representation usable by C functions.

For the reverse, C string to NSString, initialize a new NSString using stringWithUTF8String or initWithUTF8String to copy the C string data over.

10. How Do You Search an NSString for a Substring?

Locating substrings within a larger string is a frequent need.

The rangeOfString method handles this. It searches the string for the given substring, returning an NSRange with location and length.

If missing, the range’s location is NSNotFound. This facilitates substring existence checking.

11. How Do You Change NSString Case?

Case manipulation like uppercasing and lowercasing is common.

lowercaseString handles lowercasingmyString.lowercaseString returns a lowercase version.

Similarly, uppercasing uses uppercaseStringmyString.uppercaseString returns an uppercase version.

This avoids needing to manually iterate and transform each character.

12. How Does Comparing NSStrings with “isEqualToString:” vs. “==” Differ?

This NSString interview question checks your understanding of equality checking alternatives.

isEqualToString: compares string values, returning true if their contents are equivalent.

Whereas == checks for reference equality. It only returns true if both variables point to the exact same NSString object in memory.

Therefore, favor isEqualToString: for value comparisons.

13. How Do You Handle Special Characters and Formatting in NSString?

Creating strings with special characters and formatting requires escaping and placeholders:

  • Escaped characters use backslash – \ for backslash, " for quote

  • Unicode uses u plus 4-digit codepoint

  • Format specifiers like %@ insert variables into strings

14. What’s the Difference Between “”copy”” and “”strong”” NSString Properties?

Property attributes adjust how NSStrings are handled during assignment.

strong retains the string – it won’t deallocate until all strong references are removed.

copy creates a new copy of the string value

Submit an interview question

Questions and answers sent in will be looked over and edited by Toptal, LLC, and may or may not be posted, at their sole discretion.

Toptal sourced essential questions that the best iOS developers and engineers can answer. Driven from our community, we encourage experts to submit questions and offer feedback.

nsstring interview questions

Consider the following UITableViewCell constructor:

What is the purpose of the reuseIdentifier? What is the advantage of setting it to a non-nil value?

The reuseIdentifier is used to group together similar rows in an UITableView; i. e. , rows that differ only in their content, but otherwise have similar layouts.

A UITableView will normally allocate just enough UITableViewCell objects to display the content visible in the table. In the event that reuseIdentifier is not null, UITableView will first try to use an already freed UITableViewCell with the same reuseIdentifier when the table view is scrolled. If the reuseIdentifier is not set, the UITableView will have to create a new UITableViewCell object for every new item that scrolls into view. This could cause animations to lag. 2 .

What are different ways that you can specify the layout of elements in a UIView?

Here are a few common ways to specify the layout of elements in a UIView:

  • You can add an XIB file to your project, layout elements inside it, and then load the XIB in your application code (either automatically based on how files are named or by hand). You can also make a storyboard for your app with InterfaceBuilder.
  • NSLayoutConstraints let you set how elements in a view are laid out automatically. You can use this in your own code.
  • You can make CGRects that show the exact coordinates of each element and pass them to the (id)initWithFrame:(CGRect)frame method of a UIView.
  • 3 .

What’s the difference between atomic and nonatomic properties? Which one is synthesized properties’ default? When would you use one over the other? the other?.

Properties specified as atomic are guaranteed to always return a fully initialized object. This is also the default state for synthesized properties, so even though it’s best to specify atomic to avoid confusion, your properties will still be atomic if you don’t. This guarantee of atomic properties comes at a cost to performance, however. There is no risk in getting an uninitialized value for a property that you know about (e.g. g. If everyone who can access the property is already in sync in some other way, setting it to “nonatomic” can speed things up a bit.

Apply to Join Toptals Development Network

and enjoy reliable, steady, remote Freelance iOS Developer Jobs

You made a class with a global variable named NSString *startTime in its header because you wanted to keep track of the time your app was launched. Then, in the class’ implementation, you set the variable as follows:

If you then added the following line to the application:didFinishLaunchingWithOptions: method in your AppDelegate:

What do you think should be written in the debugger console? What could you do to make this work the way it should?

A message will say “Application was launched at: (null)” because the global startTime variable has not been set yet. An Objective-C class’s initialize method is only called right before the first message is sent to that class. On the other hand, whenever an Objective-C class is added to the runtime, any load methods that are defined for that class will be called.

There are a couple different ways to solve this problem.

Way to Solve #1: Changing initialize to load will yield the desired result (but be cautious about doing too much in load, as it may increase your application’s load time).

Way to Solve #2, thanks to commenter John, there is another way: create another class method on your created class. Let’s call this new method getStartTime, and all it does is return our global startTime object.

Now we change our NSLog line to:

Because we’re now sending a message to OurCreatedClass, its initialize will get called , setting startTime. The getStartTime method will then be called, and return the start time! 5 .

Consider the following code:

What is the bug in this code and what is its consequence? How could you fix it?

This is a classic example of a retain cycle. The parent will retain the children array, and the array will retain each TTChild object added to it. When a child object is made, it will also keep its parent. This means that even after the last external reference to the parent is deleted, the parent’s retain count will still be greater than zero, and it will not be deleted.

The problem can be fixed by making the child’s reference to the parent a weak reference, as shown below:

The target’s retain count will not go up with a weak reference, and it will be set to 0 when the target is finally destroyed.


If you want to make this question more difficult, think about two peers that keep track of each other in an array. You will need to use an NSPointerArray instead of an NSArray or NSMutableArray in this case: NSPointerArray *weakRefArray = [[NSPointerArray alloc] initWithOptions: NSPointerFunctionsWeakMemory];

since NSArray normally stores a strong reference to its members. 6 .

Identify the bug in the following code:

How could you fix this issue?

There is no guarantee that the block being queued will be run on the main thread when the above code uses NSOperationQueue’s addOperationWithBlock method to send work. Notice that the content of the UILabel is being updated within the body of the block. UI updates that are not executed on the main thread can lead to undefined behavior. Before something goes wrong, this code might look like it’s working fine for a long time. But UI updates should always happen on the main thread.

The easiest way to fix the possible problem is to change the block’s body so that the update is re-queued using the main thread’s queue, as shown below:

What’s the difference between an “app ID” and a “bundle ID” and what is each used for?

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.

People often mistake the App ID for the Bundle ID because they both look like strings. After making the App ID in the Member Center, you can only use the App ID Prefix that matches the Bundle ID of the Application Bundle. This is how it looks.

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. This is often used for apps that have both lite (free) and pro (paid) versions or are branded in more than one way. 8 .

What do “strong” and “weak” references mean? Why are they important? How can they be used to help manage memory and stop memory leaks?

By default, any variable that points to another object does so with what is referred to as a “strong” reference. A retain cycle occurs when two or more objects have reciprocal strong references (i.e., strong references to each other). Any such objects will never be destroyed by ARC (iOS’ Automatic Reference Counting). Even if every other object in the application releases ownership of these objects, these objects (and, in turn, any objects that reference them) will continue to exist by virtue of those mutual strong references. This therefore results in a memory leak.

Reciprocal strong references between objects should therefore be avoided to the extent possible. A way to stop this kind of memory leak, though, is to use weak references when they are needed. If you mark one of the references as weak, the retain cycle will end, and the memory leak will not happen.

To choose which of the two references should be weak, picture the objects in the retain cycle as parents and children. In this relationship, the parent should maintain a strong reference (i. e. , ownership of) its child, but the child should not maintain maintain a strong reference (i. e. , ownership of) its parent.

You might want to keep a strong reference from the Employer object to the Employee object but a weak reference from the Employee to the Employer object, if you have objects called Employer and Employee that reference each other. 9 .

Describe managed object context and the functionality that it provides.

If you have an instance of NSManagedObjectContext, a managed object context is like a temporary “scratch pad” in an app for a group of objects that are probably related. These objects collectively represent an internally consistent view of one or more persistent stores. There is only one instance of a managed object in a given context. However, there can be more than one copy of an object in different contexts.

You can think of a managed object context as an intelligent scratch pad. You make temporary copies of objects on the scratch pad when you fetch them from a persistent store. These copies then 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. You can “fetch” objects from a persistent store through a context, make changes to those objects, and then either delete the changes or commit them back to the persistent store. The context is in charge of keeping an eye on its objects for changes and keeping an undo manager open so you can finetune your undo and redo options. You can add new objects and delete objects you’ve already fetched, and then save these changes to the persistent store.
  • Notifications. A context sends notifications at different times, which can be tracked in other parts of your app if you want to.
  • Concurrency. Thread (or serialized queue) confinement is used by Core Data to keep managed objects and managed object contexts safe. In OS X v10. 7 and later and iOS v5. Since version 0 and up, you can use initWithConcurrencyType to tell the compiler what kind of concurrency pattern to use when you create a context:

For more information, see the iOS Developer Library Core Data Basics or the NSManagedObjectContext reference. 10 .

Compare and contrast the different ways of achieving concurrency in OS X and iOS.

There are basically three ways of achieving concurrency in iOS:

  • threads
  • dispatch queues
  • operation queues

The disadvantage of threads is that they relegate the burden of creating a scalable solution to the developer. You have to decide how many threads to create and adjust that number dynamically as conditions change. Also, the application assumes most of the costs associated with creating and maintaining the threads it uses.

So, instead of using threads to solve the concurrency problem, OS X and iOS like to use an asynchronous design approach.

One of the technologies for starting tasks asynchronously is Grand Central Dispatch (GCD) that relegates thread management down to the system level. All the developer has to do is define the tasks to be executed and add them to the appropriate dispatch queue. GCD takes care of creating the needed threads and scheduling tasks to run on those threads.

All dispatch queues are first-in, first-out (FIFO) data structures, so tasks are always started in the same order that they are added.

An operation queue is the Cocoa equivalent of a concurrent dispatch queue and is implemented by the NSOperationQueue class. Unlike dispatch queues, operation queues are not limited to executing tasks in FIFO order and support the creation of complex execution-order graphs for your tasks. 11 .

Will the code below log “areEqual” or “areNotEqual”? Explain your answer.

The code will output “areEqual”.

While one might think this is obvious, it’s not. Here’s why:

Comparing pointer values equates to checking if they point to the same object. If two pointers point to the same object, they will have the same value. If they point to different objects, even if those objects have the same value, the pointers will not have the same value.

In the above code snippet, firstUserName and secondUserName are each pointers to string objects. It’s easy to think that they point to different string objects, even though both of them have the same value. However, the iOS compiler optimizes references to string objects that have the same value (i. e. because it reuses them instead of allocating the same string objects twice, both pointers are actually pointing to the same address, so the condition is true. 12 .

List and explain the different types of iOS Application States.

The iOS application states are as follows:

  • State of “not running” means that the app has not been launched or was running but was stopped by the system.
  • Inactive state: The app is running in the foreground but isn’t getting any events right now. (It may be executing other code though. Most of the time, an app only stays in this state for a short time before moving on to a different one. This feature is only turned off for a short time when the user locks the screen or when the system tells the user to do something, like answer a call or text message.
  • The app is in the active state when it is running in the background and receiving events. This is the normal mode for foreground apps.
  • Background state: The app is running code in the background. Most apps go through this short phase on their way to being locked down. However, an app that asks for more time to run may stay in this state for a while. This state is also entered by an app that is launched directly into the background instead of the inactive state.
  • Suspended state: An app stays in memory but doesn’t run any code when it’s suspended. When there isn’t enough memory, the system may delete apps that aren’t being used to make room for the app that is currently running.
  • 13 .

Consider the two methods below:

What is the usage of these methods and what is difference between them?

Both methods are present in the AppDelegate. swift file. They are used to add features to the app before it launches.

The difference between these two methods are as follows:

  • application:willFinishLaunchingWithOptions—This is the first chance for your app to run code when it starts up.
  • application:didFinishLaunchingWithOptions—This method lets you do any last-minute setup work before the user sees your app.
  • 14 .

What are rendering options for JSONSerialization?

  • ChangeableContainers: dictionaries and arrays are made as variable objects, not constants.
  • MutableLeaves: In the JSON object graph, leaf strings are made up of instances of variable strings.
  • allowFragments: The parser should let top-level objects that aren’t strings or dictionaries work.

There is more to interviewing than tricky technical questions, so these are intended merely as a guide. Not every good candidate for the job will be able to answer all of them, and answering all of them doesn’t mean they are a good candidate. At the end of the day, hiring remains an art, a science — and a lot of work.

Tired of interviewing candidates? Not sure what to ask to get you a top hire?

Let Toptal find the best people for you.

Our Exclusive Network of iOS Developers

Looking to land a job as an iOS Developer?

Let Toptal find the right job for you.

Job Opportunities From Our Network

Swift String | iOS Swift Interviews – All about Swift Strings

ensuring the original can’t change. This prevents issues with mutable strings.

15. How Do You Reverse an NSString?

Reversing strings is a common operation interviewers may ask you to implement:

  • Initialize empty NSMutableString

  • Loop through original string backwards

  • Append each character to mutable string

This builds the reversal by iteratively appending from the end of the original string.

16. How Can You Parse CSV Data Using NSString?

CSV parsing routines are frequently required.

The componentsSeparatedByString: method handles this cleanly:

  • Split string by commas into array

  • Each array element is a cell

You can then process the CSV by iterating through the rows. More complex CSV handling may need a dedicated parser.

17. How Do You Filter Data Using NSString and NSPredicate?

NSPredicate filtering leverages NSString for powerful queries.


Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *