Welcome to Day 2 in the 31 Days of iOS. In yesterday’s article, we talked about getting set up for development including installing Xcode, and choosing an Apple Developer Program. Today, we’re going to talk about Objective-C. Objective-C is a little different from the programming languages used by the other popular mobile device operating systems in that, unless you’re programming for iOS or OS X, you’re not very likely to be using Objective-C. Even more so, many new developers may not have experience in any of the languages that Objective-C extends from: C and SmallTalk. As a caveat, this article isn’t intended to make you an expert Objective-C developer. Instead, it’s going to give you enough of an understanding to proceed through the rest of the series.
A Bit about Objective-C’s History
As I said above, if you’re using Objective-C, you’re most likely developing for either iOS or OS X. The reason for this starts with the NeXT company founded by Steve Jobs. In 1988, Objective-C was licensed by NeXT from it’s creators at StepStone. NeXT then used Objective-C to create it’s widely lauded tools. When Apple acquired NeXT in 1996, it used Objective-C in building OS X and took it’s tools which became Xcode and Interface Builder (which are now combined into Xcode). If you’re familiar with a lot of different programming languages then you’ll see, as we continue, how Objective-C implements object-oriented methodologies a little differently than it’s language neighbor C++ (they are both extensions of C).
Objective-C supports static and dynamic typing. This means that you can either specify an specific type as a parameter (i.e. NSDictionary) or you can specify a pointer to an object (id). We’ll see more about how this is allowed when we get into how methods are called on objects. Objective-C supports all of the simple data types available in C (int, float, short, char, etc). These primitive data types are not objects (as in many other languages). Like other languages, all complex data types inherit from a base type, NSObject. The majority of complex types that you’ll deal with in your iOS development will start with NS (NSArray, NSURLConnection, etc). As far as collection objects go (i.e. objects that contain a group of other objects) you will typically see two types: NS* and NSMutable*. For example, you’ll see NSDictionary and NSMutableDictionary. The difference between these two types is that with the NSDictionary, all elements must be inserted at creation. With NSMutableDictionary, you can insert / change / remove elements after creation. This theme carries through for all of the NS* and NSMutable* types. One last important point to cover before we move on is that for any object type, you will typically always be generating them as pointers, as opposed to a direct object. For example:
So here, you'll see code like the first line frequently. You won't see the second line.
If you’re used to other non-C languages (like PHP, Java, or C#) then this is one area that may blow your mind. Primitive data types have all the usual operators that you would expect (like +, -, /, %, etc). However, any of the more complex types, don’t. For example, you can’t add two NSNumber’s together like this:
NSNumber *numOne = ...; NSNumber *numTwo = ...; NSNumber *numThree = numOne + numTwo;
In addition, you can’t concatenate two strings like this:
NSString *stringOne = ...; NSString *stringTwo = ...; NSString *stringThree = stringOne + stringTwo;
It just doesn’t work like that in Objective-C. All of these objects instead have methods to accomplish tasks like that.
Similar to C++, classes are split into two files: the .h and the .m. The .h files contain the interface of a class and is referred to as the header file. You won’t see any of the implementation details in this file. The implementation is then in the code file, the .m file. For example, here's the interface for a class with two private variables, a property, and a single method:
The syntax for some of this bears mentioning. First our property has a locking term (nonatomic) and a storage mechanism (weak) specified. The nonatomic flag prevents the property from being locked which means that multiple threads can access it at the same time. By default, properties are atomic (so they are locked). Weak means that the property is not tied to the owner (i.e. one can be released without affecting the other). I would recommend reading more about property settings here. For the method, we have the hyphen (-) that starts the method line which means it is an instance method (as opposed to a + for a class method). Following that is the actual method name (methodToCall). The name is ended with a colon and then the first parameter’s type in paranteheses (id) and then the variable name (sender). Let’s look at the implementation now:
The only thing that really needs to be looked at here is the @synthesize line. This causes a getter and setter to be generated for the property automatically. If the property is not synthesized, we would need to write the getter and setter ourselves.
We have already looked at how methods are declared above. However, calling methods is one of the most interesting things about Objective-C and really exposes it’s SmallTalk origins. Many other programming languages use either dot notation (object.method(params)) or the arrow operator (object->method(params)). Instead of calling methods in Objective-C, you instead send messages to an object. So for example, if we were going to call the method above, we might see something like this:
Here we use the brackets to indicate that we’re going to send a message to the first object (myExampleObject). We send the message methodToCall and pass the parameter myParam. I mentioned class and instance methods earlier. If this method had been defined as a class method instead (meaning we used a + instead of a -) then we would call the method like this:
The same syntax is used here as far as sending a message goes. One thing to remember is that there isn’t a concept of private methods in Objective-C. If you create a method, it’s going to be public.
Loops and Conditionals
Objective-C supports common looping and conditionals. Here are examples of the for(each), for(count), and while loops:
Conditionals (equals, less than, greater than, etc) are the same as in other languages. One important reminder is that some operators won’t work for complex types in the way you think they will. You can’t do string concatenation with the equals operator. You can’t check for string equality either.
Memory management is interesting when it comes to iOS. Prior to 2011 and Xcode 4, developers had to manually issue retain and release messages to objects to handle memory. In other words, every aspect of memory management was still on the developers shoulders. With the release of Xcode 4, Apple introduced Automatic Reference Counting (ARC) which automatically inserted retain and release messages. It doesn’t do this in the code you’re going to be writing but inserts them at compile time. ARC also added the weak reference type we used above. This isn’t really garbage collection as you may be use to in other languages. Developers still need to be cognizant of memory issues and how their application works. iOS devices are still limited in how much memory they can use.
Can’t I develop for iOS in something else?
Today we’ve gone through a brief review of the Objective-C programming language. While far from having everything covered, after reading through this, you should have enough knowledge to trudge through the coding of the rest of the articles in the series.