MOBILE

The Language of Apple Platforms : Exploring the Objective-C File Structure

9/14/2010 5:01:22 PM
In the preceding hour, you learned how to use Xcode to create projects and navigate their files. As mentioned then, the vast majority of your time will be spent in the Classes folder of Xcode, shown in Figure 1. You’ll be adding methods to class files that Xcode creates for you when you start a project or, occasionally, creating your own class files to implement entirely new functionality in your application.
Figure 1. Most of your coding will occur within the files in the Classes folder.


Okay, sounds simple enough, but where will the coding take place? If you create a project and look in the Classes folder, you’ll see quite a few different files staring back at you.

Header/Interface Files

Creating a class creates two different files: an interface (or header) file (.h) and an implementation file (.m). The interface file is used to define a list of all of the methods and properties that your class will be using. This is useful for other pieces of code, including Interface Builder  to determine how to access information and features in your class.

The implementation file, on the other hand, is where you’ll go to write the code that makes everything defined in the header file work. Let’s review the structure of the very short, and entirely made-up, interface file in Listing 1.

Listing 1.
 1: #import 
2:
3: @interface myClass : myParent {
4: NSString *myString;
5: IBOutlet UILabel *myLabel;
6: }
7:
8: +(NSString)myClassMethod:(NSString)aString;
9:
10: -(NSDate)myInstanceMethod:(NSString)aString anotherParameter:(NSURL)aURL;
11:
12: @property (nonatomic, retain) UILabel *myLabel;
13:
14: @end


The #import Directive
1: #import 

First, in line 1, the interface file uses the #import directive to include any other interface files that our application will need to access. The string designates the specific file (in this case, UIKit, which gives us access to a vast majority of the classes). If we need to import a file, we’ll be explaining how and why in the text. The UIKit example will be included by default when Xcode sets up your classes and covers most of what you’ll need for this book’s examples.

Did You Know?: Wait a Sec, What’s a “Directive?”

Directives are commands that are added to your files that help Xcode and its associated tools build your application. They don’t implement the logic that makes your app work, but they are necessary for providing information on how your applications are structured so that Xcode knows how to deal with them.


The @interface Directive and Instance Variables

Line 3 uses the @interface directive to begin a set of lines (enclosed in {} braces) to describe all the instance variables that your class will be providing:

 3: @interface myClass : myParent  {
4: NSString *myString;
5: IBOutlet UILabel *myLabel;
6: }

In this example, a variable that contains an object of type NSString named myString is declared, along with an object of type UILabel that will be referenced by the variable myLabel. An additional keyword IBOutlet is added to the front of the UILabel declaration to indicate that this is an object that will be defined in Interface Builder.

Watch Out!

All instance variables, method declaration lines, and property declarations must end with a semicolon (;).

Notice that line 3 includes a few additional items after the @interface directive: myClass : myParent . The first of these is the name that we’re giving the class that we’re working on. Here, we’ve decided the class will be called myClass. The class name is then followed by a colon (:) and a list of the classes that this class is inheriting from (that is, the “parent” classes). Finally, the parent classes are followed by a list of “protocols” enclosed within angle brackets, <>.

By the Way

The implementation and interface files for a class will usually share the name of the class. Here, the interface file would be named myClass.h and the implementation file myClass.m.


Protocols? What’s a Protocol?

Protocols are a unique feature of Objective-C that sound complicated, but really aren’t. Sometimes you will come across features that require you to write methods to support their use—such as providing a list of items to be displayed in a table. The methods that you need to write are grouped together under a common name—this is known as a “protocol.”

Some protocol methods are required, others are optional—it just depends on the features you need. A class that implements a protocol is said to “conform” to that protocol.


Defining Methods

Lines 8 and 10 declare two methods that need to be implemented in the class:

 8: +(NSString)myClassMethod:(NSString)aString;
9:
10: -(NSDate)myInstanceMethod:(NSString)aString anotherParameter:(NSURL)aURL;

Method declarations follow a simple structure. They begin with a + or -; the + denotes a class method, whereas - indicates an instance method. Next, the type of information the method returns is provided in parentheses, followed by the name of the method itself. If the method takes a parameter, the name is followed by a colon, the type of information the method is expecting, and the variable name that the method will use to refer to that information. If multiple parameters are needed, a short descriptive label is added, followed by another colon, data type, and variable name. This pattern can repeat for as many parameters as needed.

In the example file, line 8 defines a class method named myClassMethod that returns an NSString object and accepts an NSString object as a parameter. The input parameter is made available in a variable called aString.

Line 10 defines an instance method named myInstanceMethod that returns an NSDate object, also takes an NSString as a parameter, and includes a second parameter of the type NSURL that will be available to the method via the variable aURL.

Did You Know?

Very frequently you will see methods that accept or return objects of the type id. This is a special type in Objective-C that can reference any kind of object and proves useful if you don’t know exactly what you’ll be passing to a method, or if you want to be able to return different types of objects from a single method.

Another popular return type for methods is void. When you see void used, it means that the method returns nothing.

The @property Directive

The final functional piece of the interface file is the addition of @property directives, demonstrated in line 12:

12: @property (nonatomic, retain) UILabel *myLabel;

The @property directive is used in conjunction with another command called synthesize in the implementation file to simplify how you interact with the instance variables that you’ve defined in your interface.

Traditionally, to interact with the objects in your instance variables, you have to use methods called getters and setters (or accessors and mutators, if you want to sound a bit more exotic). These methods, as their names suggest, get and set values in your instance variable objects. For example, a UILabel object, like what we’re referencing with the myLabel instance variable in line 12, represents an onscreen text label that a user can see. The object, internally, has a variety of instance variables itself, such as color, font, and the text that is displayed. To set the text, you might write something like this:

[myLabel setText:@"Hello World"];

And to retrieve the text currently displayed, you’ use the following:

theCurrentLabel=[myLabel getText];
Not too tough, but it’s not as easy as it could be. If we use @property and synthesize to define these as properties, we can simplify the code so that it looks like this:
myLabel.text=@"Hello World";
theCurrentLabel=myLabel.text;
We’ll make use of this feature nearly everywhere that we need easy access to instance variables. After we’ve given this treatment to an instance variable, we can refer to it as a property. Because of this, you’ll typically see things referred to as “properties” rather than instance variables.

Did You Know?

The attributes (nonatomic, retain) that are provided to the @property directive tell Xcode how to treat the property it creates. The first, nonatomic, informs the system that it doesn’t need to worry about different parts of the application using the property at the same time, whereas retain makes sure that the object the property refers to will be kept around. These are the attributes you should use in nearly all circumstances, so get used to typing them!

Ending the Interface File

To end the interface file, add @end on its own line. This can be seen on line 14 of our example file:

14: @end

That’s it for the interface! Although that might seem like quite a bit to digest, it covers almost everything you’ll see in an interface/header file. Now let’s look at the file where the actual work gets done: the implementation file.

Implementation Files

After you’ve defined your instance variables (or properties!) and methods in your interface file, you need to do the work of writing code to implement the logic of your application. The implementation file (.m) holds all of the “stuff” that makes your class work. Let’s take a look at Listing 3.2, a sample skeleton file myClass.m that corresponds to the interface file we’ve been reviewing.

Listing 2.
 1: #import "myClass.h"
2:
3: @implementation myClass
4:
5: @synthesize myLabel;
6:
7: +(NSString)myClassMethod:(NSString)aString {
8: // Implement the Class Method Here!
9: }
10:
11: -(NSString)myInstanceMethod:(NSString)aString anotherParameter:(NSURL)aURL {
12: // Implement the Instance Method Here!
13: }
14:
15: @end


The #import Directive

The #import directive kicks things off in line 1 by importing the interface file associated with the class:

1: #import "myClass.h"

When you create your projects and classes in Xcode, this will automatically be added to the code for you. If any additional interface files need to be imported, you should add them to the top of your interface file rather than here.

The @implementation Directive

The implementation directive, shown in line 3, tells Xcode what class the file is going to be implementing. In this case, the file should contain the code to implement myClass:

3: @implementation myClass
The @synthesize Directive

In line 5, we use the @synthesize directive to, behind the scenes, generate the code for the getters and setters of an instance variable:

5: @synthesize myLabel;

Used along with the @property directive, this ensures that we have a straightforward way to access and modify the contents of our instance variables as described earlier.

Method Implementation

To provide an area to write your code, the implementation file must restate the method definitions, but, rather than ending them with a semicolon (;), a set of curly braces, {}, is added at the end, as shown in lines 7–9 and 11–13. All the magic of your programming will take place between these braces:

 7: +(NSString)myClassMethod:(NSString)aString {
8: // Implement the Class Method Here!
9: }
10:
11: -(NSString)myInstanceMethod:(NSString)aString anotherParameter:(NSURL)aURL {
12: // Implement the Instance Method Here!
13: }

By the Way

You can add a text comment on any line within your class files by prefixing the line with the // characters. If you’d like to create a comment that spans multiple lines, you can begin the comment with the characters /* and end with */.


Ending the Interface File

To end the implementation file, add @end on its own line just like the interface file. This can be seen on line 15 of our example:

15: @end
Structure for Free

Even though we’ve just spent quite a bit of time going through the structure of the interface and implementation files, you’re rarely (if ever) going to need to type it all out by hand. Whenever you add a new class to your Xcode project, the structure of the file will be set up for you. Of course, you’ll still need to define your variables and methods, but the @interface and @implementation directives and overall file structure will be in place before you write a single line of code.

Other  
 
Most View
Nook HD - A High-Definition Tablet With The Heart Of A Reader (Part 3)
Windows Small Business Server 2011 : Installing the Second Server (part 5) - Customizing the Server
Reusing T-SQL Code - Scalar UDFs and Performance
Mobile Phones Buying Guide – April 2013 (Part 7) : Samsung Galaxy S Advance, Samsung Galaxy S Ill, Sony Xperia Go, Sony Xperia P
How To Buy…A Media Streaming Device (Part 2)
Kaser Net’sPC2 YF810-8G Android Nettop Review (Part 1)
Sony KDL-26EX553 – LCD Television
Galaxy Note 10.1 - The Pen Sets This Tablet Apart
SQL Server 2012 : Exploring SQL CLR - Security
External Drive Western Digital My Book Thunderbolt Duo
Top 10
Keep Your Laptop Safe And Secure While You Travel
8 Tips To Protect Your Business’s Wireless Network
Alternatives To Online Backups
My Cloud EX4 Wins On Features, Not Speed
Must-Know Privacy Tips For Facebook And More
Windows Phone 7 : Applying Textures (part 2) - Preparing the Effect for Texture Mapping
Windows Phone 7 : Applying Textures (part 1) - Applying the Texture to an Object
Windows 7 : Programming WMI Support (part 5) - Techniques for Testing WMI Driver Support, WMI Event Tracing
Windows 7 : Programming WMI Support (part 4) - Troubleshooting Specific WMI Problems
Windows 7 : Programming WMI Support (part 3) - Firing WMI Events