An ordered, random-access collection.
SDK
- Xcode 6.0.1+
Framework
- Swift Standard Library
Declaration
Overview
Arrays are one of the most commonly used data types in an app. You use arrays to organize your app’s data. Specifically, you use the Array
type to hold elements of a single type, the array’s Element
type. An array can store any kind of elements—from integers to strings to classes.
Swift makes it easy to create arrays in your code using an array literal: simply surround a comma-separated list of values with square brackets. Without any other information, Swift creates an array that includes the specified values, automatically inferring the array’s Element
type. For example:
You can create an empty array by specifying the Element
type of your array in the declaration. For example:
If you need an array that is preinitialized with a fixed number of default values, use the Array(repeating:
initializer.
Accessing Array Values
When you need to perform an operation on all of an array’s elements, use a for
-in
loop to iterate through the array’s contents.
Use the is
property to check quickly whether an array has any elements, or use the count
property to find the number of elements in the array.
Use the first
and last
properties for safe access to the value of the array’s first and last elements. If the array is empty, these properties are nil
.
You can access individual array elements through a subscript. The first element of a nonempty array is always at index zero. You can subscript an array with any integer from zero up to, but not including, the count of the array. Using a negative number or an index equal to or greater than count
triggers a runtime error. For example:
Adding and Removing Elements
Suppose you need to store a list of the names of students that are signed up for a class you’re teaching. During the registration period, you need to add and remove names as students add and drop the class.
To add single elements to the end of an array, use the append(_:)
method. Add multiple elements at the same time by passing another array or a sequence of any kind to the append(contents
method.
You can add new elements in the middle of an array by using the insert(_:
method for single elements and by using insert(contents
to insert multiple elements from another collection or array literal. The elements at that index and later indices are shifted back to make room.
To remove elements from an array, use the remove(at:)
, remove
, and remove
methods.
You can replace an existing element with a new value by assigning the new value to the subscript.
Growing the Size of an Array
Every array reserves a specific amount of memory to hold its contents. When you add elements to an array and that array begins to exceed its reserved capacity, the array allocates a larger region of memory and copies its elements into the new storage. The new storage is a multiple of the old storage’s size. This exponential growth strategy means that appending an element happens in constant time, averaging the performance of many append operations. Append operations that trigger reallocation have a performance cost, but they occur less and less often as the array grows larger.
If you know approximately how many elements you will need to store, use the reserve
method before appending to the array to avoid intermediate reallocations. Use the capacity
and count
properties to determine how many more elements the array can store without allocating larger storage.
For arrays of most Element
types, this storage is a contiguous block of memory. For arrays with an Element
type that is a class or @objc
protocol type, this storage can be a contiguous block of memory or an instance of NSArray
. Because any arbitrary subclass of NSArray
can become an Array
, there are no guarantees about representation or efficiency in this case.
Modifying Copies of Arrays
Each array has an independent value that includes the values of all of its elements. For simple types such as integers and other structures, this means that when you change a value in one array, the value of that element does not change in any copies of the array. For example:
If the elements in an array are instances of a class, the semantics are the same, though they might appear different at first. In this case, the values stored in the array are references to objects that live outside the array. If you change a reference to an object in one array, only that array has a reference to the new object. However, if two arrays contain references to the same object, you can observe changes to that object’s properties from both arrays. For example:
Arrays, like all variable-size collections in the standard library, use copy-on-write optimization. Multiple copies of an array share the same storage until you modify one of the copies. When that happens, the array being modified replaces its storage with a uniquely owned copy of itself, which is then modified in place. Optimizations are sometimes applied that can reduce the amount of copying.
This means that if an array is sharing storage with other copies, the first mutating operation on that array incurs the cost of copying the array. An array that is the sole owner of its storage can perform mutating operations in place.
In the example below, a numbers
array is created along with two copies that share the same storage. When the original numbers
array is modified, it makes a unique copy of its storage before making the modification. Further modifications to numbers
are made in place, while the two copies continue to share the original storage.
Bridging Between Array and NSArray
When you need to access APIs that require data in an NSArray
instance instead of Array
, use the type-cast operator (as
) to bridge your instance. For bridging to be possible, the Element
type of your array must be a class, an @objc
protocol (a protocol imported from Objective-C or marked with the @objc
attribute), or a type that bridges to a Foundation type.
The following example shows how you can bridge an Array
instance to NSArray
to use the write(to:
method. In this example, the colors
array can be bridged to NSArray
because the colors
array’s String
elements bridge to NSString
. The compiler prevents bridging the more
array, on the other hand, because its Element
type is Optional<String>
, which does not bridge to a Foundation type.
Bridging from Array
to NSArray
takes O(1) time and O(1) space if the array’s elements are already instances of a class or an @objc
protocol; otherwise, it takes O(n) time and space.
When the destination array’s element type is a class or an @objc
protocol, bridging from NSArray
to Array
first calls the copy(with:)
(- copy
in Objective-C) method on the array to get an immutable copy and then performs additional Swift bookkeeping work that takes O(1) time. For instances of NSArray
that are already immutable, copy(with:)
usually returns the same array in O(1) time; otherwise, the copying performance is unspecified. If copy(with:)
returns the same array, the instances of NSArray
and Array
share storage using the same copy-on-write optimization that is used when two instances of Array
share storage.
When the destination array’s element type is a nonclass type that bridges to a Foundation type, bridging from NSArray
to Array
performs a bridging copy of the elements to contiguous storage in O(n) time. For example, bridging from NSArray
to Array<Int>
performs such a copy. No further bridging is required when accessing elements of the Array
instance.
Note
The Contiguous
and Array
types are not bridged; instances of those types always have a contiguous block of memory as their storage.