Difference between revisions of "Writing Objective-C Class Methods"
(New page: In An Overview of Objective-C Object Oriented Programming we looked in detail about creating ''instance methods'' and mentioned in passing the existence of another type of method known...) |
(No difference)
|
Revision as of 20:23, 16 October 2009
In An Overview of Objective-C Object Oriented Programming we looked in detail about creating instance methods and mentioned in passing the existence of another type of method known as class methods. In this chapter we will look at the subject of class methods in more detail and also work through an example of adding some class methods to an Objective-C class.
Instance and Class Methods
Before we delve deeper into the subject of class methods it is first important to explain the how these differ from instance methods. Instance methods are essentially code routines that perform tasks solely on instances of a class. In our BankAccount example we created instance methods to get and set the bank account number and bank balance instance variables and to display the current values of those variables. Since each of instance of the BankAccount class will have its own instance variables containing corresponding instance specific values these methods clearly only operate at the instance level of the class.
Class methods, on the other hand, work at the class level and are common to all instances of a class. In An Overview of Objective-C Object Oriented Programming we talked about how the BankAccount class was derived from the NSObject class and as such inherited a number of class methods from this parent. In particular the BankAccount class inherited the alloc and init methods used to allocate memory for and initialize instances of the class. Since this methods are specific to the class overall, as opposed to working on different instance data encapsulated in each class instance, they are considered to be class methods.
Creating a New Class Method
In order to demonstrate the concept of class methods we are going to work on a simplified version of our BankAccount Class and add write a class method that will count the number of instances of the BankAccount class that have been initiated. To do this we are going to write a new alloc method for class called newAlloc. The ingredients we need to achieve this are as follows:
- A static variable accessible to all class instances to store the instance count
- A declaration for a our newAlloc class method in the @interface section
- A declaration for a class method to return the current value of the instance count in the @interface section
- Implementations of the two new class methods in the @implementation section
- Some code to create instances of the class using the newAlloc method and to obtain and output the instance count
Now that we know what we need to write, we can begin creating our class method example.
The @interface Section
Our interface section needs to declare two class methods. In An Overview of Objective-C Object Oriented Programming we learned that instance methods are prefixed by the minus sign (-). We declare class methods using the plus sign (+) as follows in our BankAccount.h file:
@interface BankAccount: NSObject { } +(BankAccount *) newAlloc; +(int) totalOpen; @end
We now have our two class methods declared. Note that since the newAlloc method is to return a pointer to block of memory where we will be initializing an instance of a BankAccount class we must declare the return type accordingly. As indicated, the totalopen method will return an integer. Neither method accepts any arguments.
The next step is to work on the implementation of these methods.
The @implementation Section
The first item needed in the implementation section of our class is a variable to contain the current count. Since we want this variable to be visible only within the scope of this file we will declare the variable as static (the topic of variable scope is covered in detail in Objective-C Variable Scope and Storage Class). We then need to implement our two new class methods. Lets start by writing the code in our BankAccount.m file and then analyze what we are doing:
static int openAccounts = 0; @implementation BankAccount +(BankAccount *) newAlloc { openAccounts++; return [BankAccount alloc]; } +(int) totalOpen { return openAccounts; } @end
The first line of the implementation creates a static integer variable in which we will store the count of BankAccount instances and initializes it to 0. Within the body of the implementation we then have our newAlloc class method. This method increments the current value of the openAccounts integer before calling the standard alloc class method and returning a pointer to the allocated memory space.
The totalOpen class method simply returns the current value of the openAccounts variable.
The main() Function
Now that we have our interface and implementation written, we can write our main.m file to create some instances of the BankAccount class using our newAlloc method. The code to do this involves creating some variables to store pointer to the class instances and then calling newAlloc and init:
BankAccount *account1, *account2; account1 = [[BankAccount newAlloc] init]; account2 = [[BankAccount newAlloc] init];
Having created the two instances of the class we can then call the totalOpen method to obtain the number of instances:
int count = [BankAccount totalOpen];
Note that because we are calling a class method we reference the class in the above code (i.e. BankAccount) and not either of the instances (i.e. account1 and account2).
All together, our main.m file might appear as follows:
#include "BankAccount.h" int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; BankAccount *account1, *account2; account1 = [[BankAccount newAlloc] init]; account2 = [[BankAccount newAlloc] init]; int count = [BankAccount totalOpen]; NSLog (@"Number of BankAccount instances = %i", count); [pool drain]; return 0; }
This application can be compiled from the command line as follows:
gcc -framework Foundation BankAccount.m main.m -o main
When executed, we should see output generated as follows:
2009-10-16 16:07:07.958 c[2947:10b] Number of BankAccount instances = 2