Understanding Object Duplication and Memory Strategies in Objective-C

Object duplication in Objective-C enables developers to generate independent replicas of data structures. This mechanism ensures that alterations made to a derived instance do not mutate the original source. The framework distinguishes between creating immutable and mutable duplicates through two primary instance methods.

Duplication Mechanisms

The copy method generates an immutable replica, suitable for standard string, array, and dictionary types. Conversely, mutableCopy yields a mutable variant, allowing subsequent modifications without constraints. Both operations require explicit protocol conformance:

  • NSCopying mandates the implementation of copyWithZone:.
  • NSMutableCopying requires mutableCopyWithZone:.
@protocol NSCopying <NSObject>
- (id)copyWithZone:(nullable NSZone *)zone;
@end

@protocol NSMutableCopying <NSObject>
- (id)mutableCopyWithZone:(nullable NSZone *)zone;
@end

Deep vs. Shallow Replication

The distinction between deep and shallow copying hinges on memory allocation and reference counting:

  • Deep Copy: Allocates fresh memory for the duplicate. The source and replica reside at distinct addresses, functioning independently. The new instance starts with a reference count of one.
  • Shallow Copy: Performs a pointer duplication. Both variables reference the identical memory block. The system increments the reference count rather than allocating new storage.

For immutable classes like NSString, invoking copy often results in a shallow operation for optimization, as the underlying data cannot change. Using mutableCopy on the same instance forces a deep copy to allow future mutations.

Property Attributes and Retention Policies

Declaring object properties with the copy attribute prevents external mutability from corrupting internal state. A common pattern involves storing string inputs as private copies:

@property (nonatomic, copy) NSString *userName;

Selecting the appropriate memory qualifier depends on the project's memory management model:

Scenario Qualifier Use Case
ARC copy NSString, Block objects
ARC strong General Objective-C objects
ARC weak Circular references, delegates
ARC assign Primitives, C-structs, enums
Non-ARC copy Strings, Blocks
Non-ARC retain Standard objects
Non-ARC assign Primitives, delegates

Implementing Custom Duplication

To enable duplication for bespoke classes, conform to NSCopying and define the allocation logic within the required method. The historical NSZone parameter can safely be ignored in modern development.

@interface UserRecord : NSObject <NSCopying>
@property (nonatomic, copy) NSString *identifier;
@property (nonatomic, assign) NSInteger accessLevel;
@end

@implementation UserRecord

- (id)copyWithZone:(NSZone *)zone {
    UserRecord *duplicate = [[[self class] allocWithZone:zone] init];
    if (duplicate) {
        duplicate.identifier = self.identifier;
        duplicate.accessLevel = self.accessLevel;
    }
    return duplicate;
}

@end

When a caller executes [originalUser copy], the runtime delegates to copyWithZone:. The implementation instantiates a fresh UserRecord, mirrors the current properties, and returns the isolated instance. This guarantees that subsequent updates to identifier or accessLevel on the original object remain entirely decoupled from the duplicated record.

Tags: Objective-C Memory Management NSCopying deep copy iOS Development

Posted on Sat, 09 May 2026 02:06:47 +0000 by wilzy