Top Objective-C Interview Questions and Answers(2025)

author image Hirely
at 10 Jan, 2025

Question: What is the purpose of @property and how do you define properties in Objective-C?

Answer:

In Objective-C, @property is a directive used to declare a property on an object, which is a getter and setter method for an instance variable (ivariable). It allows the automatic creation of accessors (getter and setter methods) and provides encapsulation and memory management for the instance variables, ensuring a clean and simple interface to interact with an object’s data.

Purpose of @property:

  • Simplifies Getter and Setter Creation: Instead of manually writing getter and setter methods, @property automatically generates these methods.
  • Encapsulation: Using properties, you can control access to an instance variable, which is essential for good object-oriented design.
  • Memory Management: In combination with Automatic Reference Counting (ARC), properties handle memory management (e.g., strong, weak, copy).
  • Readability: Using properties improves code readability and maintains consistency across codebases.
  • Convenience: Properties can be dynamically accessed, making object data management simpler and less error-prone.

1. Basic Syntax of @property:

A property is typically declared in the interface of a class and looks like this:

@property (attributes) type propertyName;
  • attributes: Optional keyword modifiers that define how the property behaves (e.g., memory management, atomicity, or read-only/write-only).
  • type: The data type of the property (e.g., NSString, int, NSArray).
  • propertyName: The name of the property, which corresponds to the instance variable (ivar).

Example of declaring a property:

@interface MyClass : NSObject

@property (nonatomic, strong) NSString *name;  // String property with strong reference
@property (nonatomic, assign) NSInteger age;   // Integer property with assign reference

@end

In this example:

  • name is a NSString property with a strong reference, meaning that it will retain the object and increment its reference count.
  • age is an NSInteger property with an assign reference, which is used for primitive types like int and NSInteger.

2. Common Attributes for @property:

  • nonatomic vs atomic:

    • nonatomic: Indicates that the property is not thread-safe. It’s faster but may lead to issues in multithreaded environments.
    • atomic (default for object types): Indicates that the property is thread-safe and guarantees that the getter and setter are atomic (i.e., completed in a single operation), but it might be slower.
  • Memory Management Attributes:

    • strong: Indicates that the property should retain the value, meaning it will keep a strong reference to the object.
    • weak: Indicates that the property should hold a weak reference to the object. The object will not be retained, and if no other strong references exist, the object will be deallocated.
    • copy: Used with immutable objects (e.g., NSString, NSArray) to make sure a copy of the object is retained instead of the original reference. This is especially useful when dealing with mutable objects.
    • assign: Used for primitive types (e.g., int, float) and non-object references. The value is directly assigned without retaining.
  • readwrite vs readonly:

    • readwrite (default): Allows both getter and setter methods to be automatically generated for the property.
    • readonly: Only a getter method is generated automatically; the setter must be manually defined if needed.
  • getter and setter:

    • You can manually specify getter and setter method names using the getter and setter attributes.

3. Examples of Properties with Different Attributes:

Example 1: Basic Property Declaration

@interface Person : NSObject

@property (nonatomic, strong) NSString *firstName;  // Strong reference for an object
@property (nonatomic, assign) NSInteger age;         // Assign for primitive type

@end

Here:

  • firstName is a strong property, which means the object pointed to by firstName will be retained.
  • age is an assign property because age is a primitive type (NSInteger), and it doesn’t need reference counting.

Example 2: Using readonly and setter:

@interface Car : NSObject

@property (nonatomic, readonly) NSString *modelName;  // Read-only property (no setter generated)
@property (nonatomic, assign) NSInteger year;          // Assign property (setter and getter generated)

@end

In this example:

  • modelName is a read-only property, so only a getter method will be automatically generated for it. The setter won’t be created automatically, and if needed, you would define it manually.

Example 3: Using copy:

@interface Event : NSObject

@property (nonatomic, copy) NSString *eventTitle;  // Ensures a copy of the string is retained

@end

Here:

  • The eventTitle is marked as copy, meaning that when you assign an NSString to this property, a copy of the string will be retained instead of just the reference to the original string.

Example 4: Custom Getter and Setter:

@interface Rectangle : NSObject

@property (nonatomic, assign) NSInteger width;
@property (nonatomic, assign) NSInteger height;

- (NSInteger)area;  // Custom getter method

@end

You can define a custom getter method like this:

@implementation Rectangle

- (NSInteger)area {
    return self.width * self.height;
}

@end

Here, a custom getter (area) is used instead of directly accessing the width and height properties.


4. Synthesizing Properties:

When you define properties with @property, Objective-C will automatically generate getter and setter methods for you. However, if you want to manually implement the getter or setter or customize the ivar names, you can use the @synthesize directive.

Example of Manual Synthesis:

@interface Car : NSObject

@property (nonatomic, strong) NSString *model;

@end

@implementation Car {
    NSString *_model;  // Manually declare the ivar
}

@synthesize model = _model;  // Manually synthesize the property

@end

In this case, the @synthesize directive tells the compiler to use the manually declared ivar (_model) instead of automatically generating one. You can also skip @synthesize, and the compiler will automatically synthesize the ivar with the name model.


5. Memory Management and ARC:

When you use properties in Automatic Reference Counting (ARC), the memory management of the object associated with the property is automatically handled based on the attribute you use:

  • strong: Retains the object (increases the reference count).
  • weak: Does not retain the object. If no other strong references exist, the object will be deallocated.
  • copy: Copies the object before assigning it to the property.
  • assign: Simply assigns the value without retaining it.

6. Accessing Properties:

Once a property is declared, you can access it using dot notation or getter/setter methods.

Example:

Person *person = [[Person alloc] init];

// Using dot notation
person.firstName = @"John";  // Setter
NSLog(@"%@", person.firstName);  // Getter

// Using getter/setter methods explicitly
[person setFirstName:@"John"];
NSString *firstName = [person firstName];
  • Dot notation is shorthand for accessing properties.
  • The setter method is called when you assign a value (person.firstName = @"John").
  • The getter method is called when you access the value (person.firstName).

Conclusion:

  • @property is a powerful mechanism in Objective-C to simplify the declaration and management of instance variables.
  • It automatically generates getter and setter methods, reducing the need to write boilerplate code.
  • You can control the memory management (strong, weak, copy), atomicity (nonatomic, atomic), and accessibility (readonly, readwrite) of the properties with various attributes.
  • Using dot notation, you can access properties, making your code cleaner and more readable.

Question: What are key-value coding (KVC) and key-value observing (KVO) in Objective-C?

Answer:

In Objective-C, Key-Value Coding (KVC) and Key-Value Observing (KVO) are mechanisms that allow you to access and observe properties of objects dynamically. These concepts are part of Cocoa and Cocoa Touch frameworks, and they enable more flexible data management and interaction between objects.


1. Key-Value Coding (KVC)

Key-Value Coding (KVC) is a mechanism that allows an object to access the values of its properties or instance variables using string keys, without needing to directly access the variables by name. This provides a dynamic and generalized way to interact with an object’s properties.

How KVC works:

  • Access properties using strings: You can access an object’s properties or instance variables via key strings, which can be useful in cases where you don’t know the property names at compile time, such as when dealing with serialization or dynamically generated objects.
  • Getter/Setter access: KVC provides methods like valueForKey: and setValue:forKey: to get or set property values dynamically.

Example:

@interface Person : NSObject
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@end

@implementation Person
@end

// KVC usage
Person *person = [[Person alloc] init];
[person setValue:@"John" forKey:@"firstName"];
[person setValue:@"Doe" forKey:@"lastName"];

NSString *firstName = [person valueForKey:@"firstName"];
NSString *lastName = [person valueForKey:@"lastName"];

NSLog(@"Full Name: %@ %@", firstName, lastName);  // Outputs: Full Name: John Doe

In this example:

  • setValue:forKey: is used to set values dynamically.
  • valueForKey: is used to retrieve the values dynamically.

KVC Methods:

  • setValue:forKey:: Sets a value for a given property.
  • valueForKey:: Retrieves the value for a given property.
  • setValue:forKeyPath:: Sets a value for a nested property (i.e., key path).
  • valueForKeyPath:: Retrieves a value for a nested property.

Key-Value Coding Rules:

  • The property or instance variable should follow certain naming conventions:
    • The getter method for a property firstName must be firstName or getFirstName.
    • The setter method for a property firstName must be setFirstName:.
  • KVC also supports key paths, which allows you to access nested properties (e.g., address.street).

2. Key-Value Observing (KVO)

Key-Value Observing (KVO) is a mechanism that allows an object to observe changes to a property of another object. When a property of an observed object changes, the observing object is notified automatically. KVO enables an easy way to track changes to an object’s properties and react to those changes, especially useful in model-view-controller (MVC) design patterns.

How KVO works:

  • Observe properties: You can register an object to observe changes to a specific property of another object.
  • Automatic Notification: When the property changes, KVO automatically notifies the observer.
  • Notifications: The observing object can react to the change (e.g., update the UI or perform calculations).

Example:

@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@end

@implementation Person
@end

// KVO usage
Person *person = [[Person alloc] init];
person.name = @"John";

// Observer class
@interface Observer : NSObject
@end

@implementation Observer

- (void)startObserving {
    [person addObserver:self
             forKeyPath:@"name"
                options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                context:nil];
}

- (void)stopObserving {
    [person removeObserver:self forKeyPath:@"name"];
}

// KVO callback method
- (void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary *)change
                      context:(void *)context {
    if ([keyPath isEqualToString:@"name"]) {
        NSLog(@"Name changed: %@", [change objectForKey:NSKeyValueChangeNewKey]);
    }
}

@end

In this example:

  • The Observer class is observing the name property of the Person object using the addObserver:forKeyPath: method.
  • When the name property changes, the observeValueForKeyPath:ofObject:change:context: method is automatically called.

Key Methods for KVO:

  • addObserver:forKeyPath:options:context:: Registers an observer for a property.
  • removeObserver:forKeyPath:: Removes an observer for a property.
  • observeValueForKeyPath:ofObject:change:context:: This method is called when a property value changes, and it’s used to handle the change.

KVO Options:

  • NSKeyValueObservingOptionNew: Observes the new value.
  • NSKeyValueObservingOptionOld: Observes the old value.
  • NSKeyValueObservingOptionInitial: Observes the initial value when the observer is first registered.
  • NSKeyValueObservingOptionPrior: Observes changes before they occur.

Key Points about KVO:

  • KVO is based on the setter/getter methods: KVO works by monitoring the setter method of the observed property. If the setter changes the value, KVO will notify the observer.
  • Automatic Notifications: Once you register for KVO, the system will automatically handle the notifications when the property value changes.
  • Manual Trigger: KVO does not automatically work with primitive types. To observe primitive types, you can manually trigger the change notifications using willChangeValueForKey: and didChangeValueForKey:.

3. Key Differences Between KVC and KVO

FeatureKVC (Key-Value Coding)KVO (Key-Value Observing)
PurposeProvides a way to access properties dynamically via keys.Provides a way to observe changes to properties.
Use CaseSetting or getting the value of an object’s property by key.Tracking and responding to changes in an object’s properties.
How It WorksAllows accessing properties or ivars through strings (keys).Registers observers for property changes, which are notified when values change.
MethodsvalueForKey:, setValue:forKey:addObserver:forKeyPath:, observeValueForKeyPath:ofObject:change:context:
Dynamic AccessAllows accessing properties without knowing their names at compile time.Observes changes to a property dynamically.
NotificationNo automatic notifications for changes.Automatic notifications when observed properties change.

4. Common Use Cases

KVC Use Cases:

  • Serialization: KVC is often used for serializing objects to a dictionary or JSON format.
  • Dynamic Property Access: When you need to dynamically get or set properties of objects based on variable input, such as from a configuration file or user input.

KVO Use Cases:

  • UI Updates: Automatically updating the UI when a model property changes.
  • Validation: Observing properties to trigger validation logic when a property value changes.

Conclusion:

  • KVC (Key-Value Coding) allows dynamic access to an object’s properties using key strings, providing flexibility and enabling easier interactions with object data.
  • KVO (Key-Value Observing) allows you to monitor changes to an object’s properties and react accordingly, which is particularly useful for implementing the observer design pattern, especially in Cocoa/Cocoa Touch applications.
  • Together, KVC and KVO are powerful mechanisms for building more dynamic and flexible Objective-C applications.

Read More

If you can’t get enough from this article, Aihirely has plenty more related information, such as Objective-C interview questions, Objective-C interview experiences, and details about various Objective-C job positions. Click here to check it out.

Related Posts

Trace Job opportunities

Hirely, your exclusive interview companion, empowers your competence and facilitates your interviews.

Get Started Now