An object representing a static ordered collection, for use instead of an Array
constant in cases that require reference semantics.
SDKs
- iOS 2.0+
- macOS 10.0+
- Mac Catalyst 13.0+
- tvOS 9.0+
- watchOS 2.0+
Framework
- Foundation
Declaration
class NSArray : NSObject
Overview
NSArray
and its subclass NSMutable
manage ordered collections of objects called arrays. NSArray
creates static arrays, and NSMutable
creates dynamic arrays. You can use arrays when you need an ordered collection of objects.
NSArray
is “toll-free bridged” with its Core Foundation counterpart, CFArray
. See Toll-Free Bridging for more information on toll-free bridging.
Creating NSArray Objects Using Array Literals
In addition to the provided initializers, such as init
, you can create an NSArray
object using an array literal.
let array: NSArray = [someObject, "Hello, World!", 42]
In Objective-C, the compiler generates code that makes an underlying call to the init(objects:
method.
id objects[] = { someObject, @"Hello, World!", @42 };
NSUInteger count = sizeof(objects) / sizeof(id);
NSArray *array = [NSArray arrayWithObjects:objects
count:count];
You should not terminate the list of objects with nil
when using this literal syntax, and in fact nil
is an invalid value. For more information about object literals in Objective-C, see Working with Objects in Programming with Objective-C.
In Swift, the NSArray
class conforms to the ArrayLiteralConvertible protocol, which allows it to be initialized with array literals. For more information about object literals in Swift, see Literal Expression in The Swift Programming Language (Swift 4.1).
Accessing Values Using Subscripting
In addition to the provided instance methods, such as object(at:)
, you can access NSArray
values by their indexes using subscripting.
let value = array[3]
Subclassing Notes
There is typically little reason to subclass NSArray
. The class does well what it is designed to do—maintain an ordered collection of objects. But there are situations where a custom NSArray
object might come in handy. Here are a few possibilities:
Changing how
NSArray
stores the elements of its collection. You might do this for performance reasons or for better compatibility with legacy code.Acquiring more information about what is happening to the collection (for example, statistics gathering).
Methods to Override
Any subclass of NSArray
must override the primitive instance methods count
and object(at:)
. These methods must operate on the backing store that you provide for the elements of the collection. For this backing store you can use a static array, a standard NSArray
object, or some other data type or mechanism. You may also choose to override, partially or fully, any other NSArray
method for which you want to provide an alternative implementation.
You might want to implement an initializer for your subclass that is suited to the backing store that the subclass is managing. If you do, your initializer must invoke one of the designated initializers of the NSArray
class, either init()
or init(objects:
. The NSArray
class adopts the NSCopying
, NSMutable
, and NSCoding
protocols; custom subclasses of NSArray
should override the methods in these protocols as necessary.
Remember that NSArray
is the public interface for a class cluster and what this entails for your subclass. You must provide the storage for your subclass and implement the primitive methods that directly act on that storage.
Alternatives to Subclassing
Before making a custom subclass of NSArray
, investigate NSPointer
and the corresponding Core Foundation type, CFArray. Because NSArray
and CFArray
are “toll-free bridged,” you can substitute a CFArray
object for a NSArray
object in your code (with appropriate casting). Although they are corresponding types, CFArray
and NSArray
do not have identical interfaces or implementations, and you can sometimes do things with CFArray
that you cannot easily do with NSArray
. For example, CFArray
provides a set of callbacks, some of which are for implementing custom retain-release behavior. If you specify NULL
implementations for these callbacks, you can easily get a non-retaining array.
If the behavior you want to add supplements that of the existing class, you could write a category on NSArray
. Keep in mind, however, that this category will be in effect for all instances of NSArray
that you use, and this might have unintended consequences. Alternatively, you could use composition to achieve the desired behavior.