Array traversal is a common requirement in encoding. Let's find out what methods are available in iOS and what features are there.
Because iOS is compatible with the C language, the most common for loop traversal in the C language is no problem.
The array used in this article is the obtained System Language array, with more than 30 pieces of data. Although it is not enough to simulate a large amount of data, there is no problem with method verification.
NSArray *langArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"AppleLanguages"];
The first method is the evolution of the most familiar C language:
For (int I = 0; I
This method is the most common and efficient method, but it also has advantages. First, it is convenient for processing the lower mark, that is, it is very easy if I want to handle the I = 10, the other is convenient reverse traversal.
The NSEnumerator in Objective-C 1.0 can also be traversed. The Code is as follows:
NSEnumerator *enumerator = [langArray objectEnumerator]; id object; while ((object = [enumerator nextObject]) != nil) { NSLog(@"langArray=%@", object); }
Here we can see that there is no subscript, and we can use the nextObject method to traverse it. The advantage of this method is that it is similar for Traversing NSDictionary and NSSet code. It is inconvenient to handle the underlying object, and the reverseObjectEnumerator method is required for reverse traversal.
When Objective-C grew to 2.0, it had a fast traversal function. The Code is as follows:
for (id object in langArray) { NSLog(@"langArray=%@", object); }
The code here is concise and clear. It has been my first choice to write code for a long time. It is also the most efficient, but the inconvenience is also obvious. If the algorithm requires to know the subscript of the array, this method will be blind. In addition, the reverse direction needs to be implemented through [langArray reverseObjectEnumerator.
After the block is removed, the enumerateObjectsUsingBlock: method is added to iOS. The Code is as follows:
[langArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSLog(@"idx=%d, id=%@", idx, obj); }];
Here we can see that the parameters in the block include object, subscript, and whether to stop traversal. It should be said that this can meet all basic traversal requirements, including subscript and running object, and whether to continue traversing. But what about reverse traversal? Apple provides another method:
[langArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSLog(@"idx=%d, id=%@", idx, obj); }];
This enumerateobjectswitexceptions: usingBlock: The method has one more parameter than enumerateObjectsUsingBlock: this parameter specifies the traversal order.
Speaking of this, if we choose forward traversal, are these two methods the same? The answer is no. In the enumerateobjectswitexceptions: usingBlock: method, if the NSEnumerationConcurrent sequence is specified, the underlying layer uses GCD to process concurrent execution. The specific implementation may use the dispatch group. That is to say, this will be implemented concurrently using multiple threads, but it is not guaranteed to be executed in order, but the efficiency must be superb!
Let's take a look at the printed results:
2014-06-17 15:46:44.413 testStoryboard[2703:3503] idx=32, id=hu2014-06-17 15:46:44.413 testStoryboard[2703:1303] idx=16, id=ru2014-06-17 15:46:44.416 testStoryboard[2703:3503] idx=33, id=vi2014-06-17 15:46:44.412 testStoryboard[2703:60b] idx=0, id=zh-Hant2014-06-17 15:46:44.417 testStoryboard[2703:1303] idx=17, id=pl2014-06-17 15:46:44.417 testStoryboard[2703:60b] idx=1, id=zh-Hans2014-06-17 15:46:44.417 testStoryboard[2703:1303] idx=18, id=tr2014-06-17 15:46:44.419 testStoryboard[2703:60b] idx=2, id=en2014-06-17 15:46:44.419 testStoryboard[2703:1303] idx=19, id=uk2014-06-17 15:46:44.421 testStoryboard[2703:60b] idx=3, id=fr2014-06-17 15:46:44.421 testStoryboard[2703:1303] idx=20, id=ar2014-06-17 15:46:44.421 testStoryboard[2703:60b] idx=4, id=de2014-06-17 15:46:44.422 testStoryboard[2703:60b] idx=5, id=ja2014-06-17 15:46:44.422 testStoryboard[2703:60b] idx=6, id=nl2014-06-17 15:46:44.421 testStoryboard[2703:1303] idx=21, id=hr2014-06-17 15:46:44.423 testStoryboard[2703:60b] idx=7, id=it2014-06-17 15:46:44.423 testStoryboard[2703:1303] idx=22, id=cs2014-06-17 15:46:44.423 testStoryboard[2703:60b] idx=8, id=es2014-06-17 15:46:44.424 testStoryboard[2703:1303] idx=23, id=el2014-06-17 15:46:44.424 testStoryboard[2703:60b] idx=9, id=ko2014-06-17 15:46:44.424 testStoryboard[2703:1303] idx=24, id=he2014-06-17 15:46:44.425 testStoryboard[2703:60b] idx=10, id=pt2014-06-17 15:46:44.425 testStoryboard[2703:60b] idx=11, id=pt-PT2014-06-17 15:46:44.425 testStoryboard[2703:1303] idx=25, id=ro2014-06-17 15:46:44.426 testStoryboard[2703:60b] idx=12, id=da2014-06-17 15:46:44.426 testStoryboard[2703:1303] idx=26, id=sk2014-06-17 15:46:44.426 testStoryboard[2703:60b] idx=13, id=fi2014-06-17 15:46:44.426 testStoryboard[2703:1303] idx=27, id=th2014-06-17 15:46:44.427 testStoryboard[2703:60b] idx=14, id=nb2014-06-17 15:46:44.427 testStoryboard[2703:1303] idx=28, id=id2014-06-17 15:46:44.428 testStoryboard[2703:60b] idx=15, id=sv2014-06-17 15:46:44.428 testStoryboard[2703:1303] idx=29, id=ms2014-06-17 15:46:44.429 testStoryboard[2703:1303] idx=30, id=en-GB2014-06-17 15:46:44.429 testStoryboard[2703:1303] idx=31, id=ca
From this result, we can see that the entire array is indeed traversed, but the concurrency is sequential from start to end -- that is, the dispatch group is used. This is advantageous for improving efficiency when traversing large arrays and having mutual independence. I like it!
In iOS, apart from arrays, NSDictionary and NSSet data are also called collection data. traversal is similar, but traversal is less frequent than array, and the method is similar.