Here at iCodeblog, we have been showing you guys how to create many different types of applications from the ground up. Well, today I decided to do something different and get down to some of the nitty gritty of a structure we rely heavily on in objective-C.
The NSArray is a huge workhorse that we use quite frequently without even thinking about it. The NSArray class isn’t just your ordinary array. Not only does it provide random access, but it also dynamically re-sizes when you add new objects to it and has many methods to make our lives easier. While I won’t go over every method in NSArray (there are quite a few), I will discuss some of the more important ones that are most commonly used. Let’s take a closer look at this class.
Factory Methods
Factory methods are static methods that build new instances of NSArrays from given parameters and return them. The table below details on all of the factory methods for the NSArray class.
| + (id)array | Creates and returns an empty array |
| + (id)arrayWithArray:(NSArray *)anArray | Creates and returns an array containing the objects in another given array. |
| + (id)arrayWithContentsOfFile:(NSString *)aPath | Creates and returns an array containing the contents of the file specified by a given path. * The file must be of type .plist for this method to work |
| + (id)arrayWithContentsOfURL:(NSURL *)aURL | Similar to arrayWithContentsOfFile except it will load the .plist remotely from a given website. This would be a very simple way to get data from a web service. |
| + (id)arrayWithObject:(id)anObject | Creates and returns an array containing a given object. This will just be a 1 element array |
| + (id)arrayWithObjects:(id)firstObj, … | This method is used when you have multiple objects on hand and want easily insert them into an array. Make sure the last element you add is nil or this method won’t work. |
| + (id)arrayWithObjects:(const id *)objects count:(NSUInteger)count | Creates and returns an array that includes a given number of objects from a given C array. |
Here is some example usage of building NSArrays with these factory methods…
// I am using strings, but you can add just about any object to an NSArray // Creates an NSArray with one object NSArray * myArray = [NSArray arrayWithObject:@"foo"]; // Creates an NSArray with multiple objects. Don't forget to add nil as the last object NSArray * myArray2 = [NSArray arrayWithObjects:@"foo",@"bar",@"baz",nil]; // Creates an NSArray from another NSArray NSArray * myArray3 = [NSArray arrayWithArray:myArray2]; // This will create an NSArray from data on iCodeBlog. Go ahead and try it out, this file exists on our servers and contains valid data. NSArray * myArray4 = [NSArray arrayWithContentsOfURL:[NSURL URLWithString:@"http://icodeblog.com/wp-content/uploads/2009/08/foo.plist"]];
You can also choose not to use factory methods and just use the normal NSArray initializers. They are pretty much the same as the factory methods only you do the allocation yourself. An example of this might be:
NSArray * foo = [[NSArray alloc] initWithObjects:@"foo",@"bar",@"baz",nil];
Accessing The NSArray
Apple has provided us with many great methods for getting data out of an NSArray as well as information about it. Here is a table of methods and their descriptions.
| - (BOOL)containsObject:(id)anObject | Returns true if a given object is found in the array, false otherwise |
| - (NSUInteger)count | Returns the size of the array |
| - (id)lastObject | Returns the last object in the array (the one with the highest index) |
| - (id)objectAtIndex:(NSUInteger)index | Gives you random access to the array. Returns the object at a given index. |
These are just a few of the accessor methods of NSArray and most likely the only ones you will need to use.
Searching The Array
If you are looking for the index of an object in an array, there is really only one method you need to use. That method is indexOfObject: . An example of usage might be:
NSString * f = @"foo"; NSString * b = @"bar"; NSString * z = @"baz"; NSArray * myArray2 = [NSArray arrayWithObjects:f,b,z,nil]; NSInteger idx = [myArray2 indexOfObject:b]; // This would return 1 (since NSArrays are 0 - indexed)
This is much cleaner code than looping over the entire array to find an object. It’s probably more efficient too as Apple is pretty clean in how they code things.
Sending Message To Objects In The Array
Ok, so this is pretty cool. Say you have an array of objects that all need to do something. For example, an array of bullets, and you want all of the bullets to move forward one pixel. Rather than looping over each bullet object in the bullets array and calling [bullet move], you can do it in one method call on the array. This method is called – (void)makeObjectsPerformSelector:(SEL)aSelector and here is an example of usage.
// Lets pretend the bullet object has a method called move // and there is an array of 50 bullets [bullets makeObjectsPerformSelector:@selector(move)];
And that’s it… The move method will now be called on every bullet object in the array with this one method call. Very clean and easy to use. Now, if the method you want to call takes an argument, there is the – (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)anObject method. This will allow you to pass an object to each method being called.
Sorting Arrays
Apple has provided us with some very slick ways to sort an NSArray. I will not go into too much detail here as I have a full tutorial planned dedicated to sorting arrays. For now, I will just show you how to sort an NSArray of NSStrings. The method we will be using is sortedArrayUsingSelector. Here is the example usage.
NSArray *sortedArray = [myArray2 sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; // This will return a sorted array that looks like [@"bar",@"baz",@"foo"]
You can plug in any of the string compare functions there to compare the strings. If you are sorting an NSArray of custom objects (like users), you can overwrite the compare method for that object and pass compare in for the selector. Just make sure you remember the : at the end of the method.
Looping Through Arrays
So if you are reading this, I assume you have seen a for loop before. ex: for(int x=0; x < … This would most likely not be a good way to enumerate an NSArray as Apple has provided a much nice way for doing so. There are some situations where this method would be preferred (like when u need to calculate the indices or something). But in most cases, you will want to use the special for loop provided by Apple. If you have ever coded PHP, it is much like the foreach loop. Here is an example:
for(NSString * myStr in myArray2) { NSLog(myStr); }
This will loop over myArray2 and pring each element in that array. Very clean and efficient.
Saving Arrays For Later
There is an Array of ways to save data on the iPhone (Pun intended). One way is to simply dump the array to a file. This will write out the NSArray to a plist file on disk that can be loaded later using the arrayWithContentsOfFile method of NSArray. That method is rightfully named writeToFile. The example usage for it is as follows.
NSArray * myArray2 = [NSArray arrayWithObjects:@"foo",@"bar",@"baz",nil]; [myArray2 writeToFile:filePath atomically:YES];
And there you have it! You are probably wondering what the atomically variable means. Me too… Just kidding. If YES, the file will be written to a temp location and then renamed to its final destination. This is put in place to guarantee that the file won’t be corrupted even if the system crashes (rename will be much faster than write). Why is this needed you ask? Consider this scenario.
You want to write a huge array to disk to save it for later. When your app starts it checks the disk to see if this file exists, if it does it loads an NSArray from it. If it doesn’t it creates a new NSArray. Say the last time the app ran, the system crashed while the file was being written. If atomically was set to NO, the original file would be corrupt and now the application would be loading corrupt data every time it starts from now on (most likely causing a crash). However, if you set atomically to YES, the temp file would get corrupted and the app would never see it. That way, the next time the app starts it will create a new fresh NSArray and all will be good.
Good rule of thumb, set atomically to YES.
That concludes our tutorial on NSArray. If you have any questions or comments, feel free to post them in the comments section or write me on twitter.


23 Comments
Thank you for this excellent article! I really like short and concise reviews of basic objects. It gives me a fast high level view of a complex topic. It also affirms my existing knowledge while at the same time teaches me new things.
Way to go! Please keep up the great work.
Nicely said J.
Thanks Brandon!
Good article… Didn’t realize you could do that “fire a method on all objects in this array” thing! Very useful!
Wow, I didn’t know about the selector either… that terminology finally makes sense!
P.S. The write array method was also new to me, appreciate your article!
Could you explain predicates as a way to search an array ?
This is brilliant! You explained in such few words what I was trying to understand by reading volumes. Keep up the good work and keep posting Objective-C tutorials!
Excellent as always. Thanks.
Nice explanation, short and direct. You help a lot to us new developers.
You rocks.
The tutorial is good – while the advertisement that appears is not. Some might argue – what is wrong – to me “Why would you show someone in Bra and Panties?”
@Baskaran Yeah, I appologize for that. The ads are randomly pulled every day from adBrite.com. We have no control over it. As I am typing, there is an ad for Manga, which is completely unrelated to our site. I will look into this.
Honestly, reading this blog is much easier to understand than studying the reference book from the AppDev itself. Thanks for everything, Brandon!
But i really need to know one thing….how do we connect an application to another? Like a view-based application to a utility based or something like that?
hello, how do i loop through an array in an xml?
@Mia: the only way to *connect* two applications is using the URL schema, which will allow you to launch one application from another with parameters.
Here is a good reading on this topic: http://bit.ly/YS49o
Good luck …
hi,
hmmm… how to create an object array? i mean adding objects to an array. the objects are the child of a class.. lets take the array of bullets for example.
is it:
NSMutableArray *bullet_array = [[NSMutableArray alloc] init];
bullets_obj = [[bullet_class alloc] init];
[bullet_array addObject:bullets_obj];
Please advice.. thanks…
exemplary work. You have gained a new reader. I hope you can keep up the good work and I await more of your excellent posts.
float purchase = 1234.50f;
float sale = 987.20f;
NSNumber *purchaseObject = [NSNumber numberWithFloat:purchase];
NSNumber *saleObject = [NSNumber numberWithFloat:sale];
NSArray *array = [NSArray arrayWithObjects: date, nameField.text, purchaseObject, saleObject, nil];
[array writeToFile:@"MyArray.plist" atomically:YES];
// read a file
NSArray *phrase2 = [NSArray arrayWithContentsOfFile:@"MyArray.plist"];
NSLog(@”%@”,phrase2);
RESULT MyArray.plist
Root
item 0 date 2010-03-10 12:21:33 +0200 >> show date only ?how to remove time
item 1 string Harry >> ok right
item 2 number 1234.5 >> would prefer 1,234.50 formatted
item 3 number 987.2000122070312 >> would prefer 987.20 formatted.
I would appreciate it if you could help me to convert the code. To look like the formatted version shown. Regards
Cool post
array functions have always been hard to get to undestand for me.
Hi.
I`m working around with the iPhone SDK and want to save my array data to an plist.
I use the writeToFile method above.
NSString *pfad = [[NSBundle mainBundle] pathForResource:@”Test” ofType:@”plist”];
[personenDaten writeToFile:(NSString *)pfad atomically:YES];
But nothing is written to my plist file. Even no error will occur.
I have an array with three NSStrings and an plist with one array with three items.
Any ideas?
So, I dif find out that he`s saving them temorarely, so I can use them aus long as I don`t switch the phone off. But he`s not saving in the plist.
Terrific primer on arrays.
Many thanks.
That is cool essential tutorial about NSArray.
Thanks
smaeung
I think it is a very good arcticle.
Is it posible to have a structure (ex. name, adress, po-no, and so) in the array ? And if it is how to write to and read from file. I have search but i can’nt find a solution.
Sir,
In my project i have used a counter which increments the integer value when i clicked the movie button.Actually i have played a movie from server and i want to know that how many time from each user watch this movie.
so when i click the movie button the counter value increment and automatically saved into plist.and now i want to read the data automatically from plist into server.so please help me.i have never worked on server so please give me a full detail about this.
Thanks and Regards,
IHSAN ULLAH KHAN
3 Trackbacks
[...] more here: Objective-C Tutorial: NSArray | iCodeBlog Share and [...]
[...] Objective-C Tutorial: NSArray Tuto Objective-C sur NSArray [...]
[...] the success of our las API tutorial on NSArray, I thought I would do another walkthrough, this time on UITextField. I will be explaining all of [...]