If you first learn Objective-C or Java and then move to Swift, there is one point you are bound to encounter.
That point is the question, “How do I clone an object?”
It is easy to go searching for a method like clone(), but in Swift you rarely need to.
Let me give you the conclusion first.
Thanks to value types such as structs and arrays and its Copy-on-Write (deferred copying) optimization, Swift replaces the Prototype pattern from design patterns at the language level.
You do not need to design a separate pattern to clone an object; simply assigning the value gives you a safe copy.
This article explains what the Prototype pattern originally solved and how Swift’s value types and Copy-on-Write naturally absorb that role, with examples.
To distinguish the types of copying, Shallow copy vs. deep copy provides the foundation. When class cloning is required, Swift Prototype pattern and NSCopying presents the alternative.
The Problem the Prototype Pattern Originally Solved
The Prototype pattern is a creational GoF design pattern.
The idea is simple: instead of creating a new object from scratch, clone an existing object to obtain a new instance.
Why was this necessary?
In languages such as Objective-C and Java, objects are mostly reference types.
Assigning an object to a variable copies only the address pointing to the same object, not the value itself.
As a result, changing A also changes B.
To avoid this, developers created clone() or copy() methods that returned a “true copy.”
The Prototype pattern is a tool for this situation.
- When object creation is expensive and multiple similar objects are needed
- When an independent copy is needed without touching the original
- When you want the object itself to own the cloning logic
Swift Value Types: Assignment Completes the Copy
Swift structs and enums, along with standard types such as Array, Dictionary, and String, are all value types.
Value types are copied when assigned or passed to a function.
In other words, the language creates the copy for you.
The example makes this much clearer.
struct Point { var x: Int; var y: Int }
var a = Point(x: 1, y: 2)
var b = a // the value is copied at this moment
b.x = 99
// a.xis still 1, b.xonly 99
b = aThis single line takes over what the clone() of the Prototype pattern used to do.
No separate cloning method or copy protocol adoption is required.
The original a is safely protected, and b becomes a completely independent copy.
The troublesome bugs caused by objects becoming entangled cannot occur in this structure in the first place.
How Copy-on-Write Solves the Performance Problem
A natural concern arises here.
“If everything is copied on every assignment, won’t large arrays become too slow?”
That is a valid point. This is exactly why Swift uses Copy-on-Write, or CoW.
CoW works as follows.
When a value is assigned, the internal storage is initially shared. The actual data copy is deferred.
When either side attempts to modify the value, the real copy is finally made.
| Timing | Internal operation | Cost |
|---|---|---|
| On assignment | Shared storage (reference only) | Very low |
| When only reading | Sharing continues | No copy |
| When modifying the value | Copied for real at this point | Occurs only at this point |
This lets developers enjoy the safety of value types without paying unnecessary copying costs.
If you only read the value and never modify it, no copy occurs at all.
This CoW is already built into standard library types such as Array, Dictionary, Set, and String.
The language and standard library handle it automatically, so we do not need to implement it ourselves.
Are There Still Cases Where the Prototype Pattern Is Needed?
“So is the Prototype pattern completely obsolete in Swift?”
Not necessarily.
There are situations where you need classes: when reference semantics are essential, when interoperability with Objective-C is required, or when inheritance is needed.
In these cases, if you need an independent copy of a class instance, you still have to implement the cloning logic yourself.
Swift provides the NSCopying protocol and copy(), which are essentially the traditional form of the Prototype pattern.
This way of thinking makes the distinction easier.
- Use structs and value types → Assignment completes the copy; the Prototype pattern is unnecessary
- Classes are essential → Implement cloning logic yourself when needed; this is where the pattern survives
That is why the Swift community often advises, “Consider value types first.”
When value types are the default, the cloning problem itself disappears.
Wrapping Up
Trying to force a design pattern from an unfamiliar language into your code often makes it more complex.
In Swift, remembering that value types and Copy-on-Write naturally fill the role of the Prototype pattern will make cloning concerns much lighter.
The next time you need to copy an object, before looking for clone(), ask yourself, “Could I turn this into a struct?” It will surely help.

