]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/doc/gcc/gnu-objective-c-features/fast-enumeration.rst
sphinx: copy files from texi2rst-generated repository
[thirdparty/gcc.git] / gcc / doc / gcc / gnu-objective-c-features / fast-enumeration.rst
1 ..
2 Copyright 1988-2022 Free Software Foundation, Inc.
3 This is part of the GCC manual.
4 For copying conditions, see the copyright.rst file.
5
6 .. _fast-enumeration:
7
8 Fast Enumeration
9 ****************
10
11 .. toctree::
12 :maxdepth: 2
13
14
15 .. ================================
16
17 .. _using-fast-enumeration:
18
19 Using Fast Enumeration
20 ^^^^^^^^^^^^^^^^^^^^^^
21
22 GNU Objective-C provides support for the fast enumeration syntax:
23
24 .. code-block:: objective-c
25
26 id array = ...;
27 id object;
28
29 for (object in array)
30 {
31 /* Do something with 'object' */
32 }
33
34 ``array`` needs to be an Objective-C object (usually a collection
35 object, for example an array, a dictionary or a set) which implements
36 the 'Fast Enumeration Protocol' (see below). If you are using a
37 Foundation library such as GNUstep Base or Apple Cocoa Foundation, all
38 collection objects in the library implement this protocol and can be
39 used in this way.
40
41 The code above would iterate over all objects in ``array``. For
42 each of them, it assigns it to ``object``, then executes the
43 ``Do something with 'object'`` statements.
44
45 Here is a fully worked-out example using a Foundation library (which
46 provides the implementation of ``NSArray``, ``NSString`` and
47 ``NSLog``):
48
49 .. code-block:: objective-c
50
51 NSArray *array = [NSArray arrayWithObjects: @"1", @"2", @"3", nil];
52 NSString *object;
53
54 for (object in array)
55 NSLog (@"Iterating over %@", object);
56
57 .. ================================
58
59 .. _c99-like-fast-enumeration-syntax:
60
61 C99-Like Fast Enumeration Syntax
62 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
63
64 A c99-like declaration syntax is also allowed:
65
66 .. code-block:: objective-c
67
68 id array = ...;
69
70 for (id object in array)
71 {
72 /* Do something with 'object' */
73 }
74
75 this is completely equivalent to:
76
77 .. code-block:: objective-c
78
79 id array = ...;
80
81 {
82 id object;
83 for (object in array)
84 {
85 /* Do something with 'object' */
86 }
87 }
88
89 but can save some typing.
90
91 Note that the option :option:`-std=c99` is not required to allow this
92 syntax in Objective-C.
93
94 .. ================================
95
96 .. _fast-enumeration-details:
97
98 Fast Enumeration Details
99 ^^^^^^^^^^^^^^^^^^^^^^^^
100
101 Here is a more technical description with the gory details. Consider the code
102
103 .. code-block:: objective-c
104
105 for (object expression in collection expression)
106 {
107 statements
108 }
109
110 here is what happens when you run it:
111
112 * ``collection expression`` is evaluated exactly once and the
113 result is used as the collection object to iterate over. This means
114 it is safe to write code such as ``for (object in [NSDictionary
115 keyEnumerator]) ...``.
116
117 * the iteration is implemented by the compiler by repeatedly getting
118 batches of objects from the collection object using the fast
119 enumeration protocol (see below), then iterating over all objects in
120 the batch. This is faster than a normal enumeration where objects are
121 retrieved one by one (hence the name 'fast enumeration').
122
123 * if there are no objects in the collection, then
124 ``object expression`` is set to ``nil`` and the loop
125 immediately terminates.
126
127 * if there are objects in the collection, then for each object in the
128 collection (in the order they are returned) ``object expression``
129 is set to the object, then ``statements`` are executed.
130
131 * ``statements`` can contain ``break`` and ``continue``
132 commands, which will abort the iteration or skip to the next loop
133 iteration as expected.
134
135 * when the iteration ends because there are no more objects to iterate
136 over, ``object expression`` is set to ``nil``. This allows
137 you to determine whether the iteration finished because a ``break``
138 command was used (in which case ``object expression`` will remain
139 set to the last object that was iterated over) or because it iterated
140 over all the objects (in which case ``object expression`` will be
141 set to ``nil``).
142
143 * ``statements`` must not make any changes to the collection
144 object; if they do, it is a hard error and the fast enumeration
145 terminates by invoking ``objc_enumerationMutation``, a runtime
146 function that normally aborts the program but which can be customized
147 by Foundation libraries via ``objc_set_mutation_handler`` to do
148 something different, such as raising an exception.
149
150 .. ================================
151
152 .. _fast-enumeration-protocol:
153
154 Fast Enumeration Protocol
155 ^^^^^^^^^^^^^^^^^^^^^^^^^
156
157 If you want your own collection object to be usable with fast
158 enumeration, you need to have it implement the method
159
160 .. code-block::
161
162 - (unsigned long) countByEnumeratingWithState: (NSFastEnumerationState \*)state
163 objects: (id \*)objects
164 count: (unsigned long)len;
165
166 where ``NSFastEnumerationState`` must be defined in your code as follows:
167
168 .. code-block:: objective-c
169
170 typedef struct
171 {
172 unsigned long state;
173 id *itemsPtr;
174 unsigned long *mutationsPtr;
175 unsigned long extra[5];
176 } NSFastEnumerationState;
177
178 If no ``NSFastEnumerationState`` is defined in your code, the
179 compiler will automatically replace ``NSFastEnumerationState *``
180 with ``struct __objcFastEnumerationState *``, where that type is
181 silently defined by the compiler in an identical way. This can be
182 confusing and we recommend that you define
183 ``NSFastEnumerationState`` (as shown above) instead.
184
185 The method is called repeatedly during a fast enumeration to retrieve
186 batches of objects. Each invocation of the method should retrieve the
187 next batch of objects.
188
189 The return value of the method is the number of objects in the current
190 batch; this should not exceed ``len``, which is the maximum size of
191 a batch as requested by the caller. The batch itself is returned in
192 the ``itemsPtr`` field of the ``NSFastEnumerationState`` struct.
193
194 To help with returning the objects, the ``objects`` array is a C
195 array preallocated by the caller (on the stack) of size ``len``.
196 In many cases you can put the objects you want to return in that
197 ``objects`` array, then do ``itemsPtr = objects``. But you
198 don't have to; if your collection already has the objects to return in
199 some form of C array, it could return them from there instead.
200
201 The ``state`` and ``extra`` fields of the
202 ``NSFastEnumerationState`` structure allows your collection object
203 to keep track of the state of the enumeration. In a simple array
204 implementation, ``state`` may keep track of the index of the last
205 object that was returned, and ``extra`` may be unused.
206
207 The ``mutationsPtr`` field of the ``NSFastEnumerationState`` is
208 used to keep track of mutations. It should point to a number; before
209 working on each object, the fast enumeration loop will check that this
210 number has not changed. If it has, a mutation has happened and the
211 fast enumeration will abort. So, ``mutationsPtr`` could be set to
212 point to some sort of version number of your collection, which is
213 increased by one every time there is a change (for example when an
214 object is added or removed). Or, if you are content with less strict
215 mutation checks, it could point to the number of objects in your
216 collection or some other value that can be checked to perform an
217 approximate check that the collection has not been mutated.
218
219 Finally, note how we declared the ``len`` argument and the return
220 value to be of type ``unsigned long``. They could also be declared
221 to be of type ``unsigned int`` and everything would still work.