34,333
edits
Changes
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...
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:
<pre>
@interface BankAccount: NSObject
{
}
+(BankAccount *) newAlloc;
+(int) totalOpen;
@end
</pre>
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:
<pre>
static int openAccounts = 0;
@implementation BankAccount
+(BankAccount *) newAlloc
{
openAccounts++;
return [BankAccount alloc];
}
+(int) totalOpen
{
return openAccounts;
}
@end
</pre>
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'':
<pre>
BankAccount *account1, *account2;
account1 = [[BankAccount newAlloc] init];
account2 = [[BankAccount newAlloc] init];
</pre>
Having created the two instances of the class we can then call the totalOpen method to obtain the number of instances:
<pre>
int count = [BankAccount totalOpen];
</pre>
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:
<pre>
#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;
}
</pre>
This application can be compiled from the command line as follows:
<pre>
gcc -framework Foundation BankAccount.m main.m -o main
</pre>
When executed, we should see output generated as follows:
<pre>
2009-10-16 16:07:07.958 c[2947:10b] Number of BankAccount instances = 2
</pre>
== 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:
<pre>
@interface BankAccount: NSObject
{
}
+(BankAccount *) newAlloc;
+(int) totalOpen;
@end
</pre>
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:
<pre>
static int openAccounts = 0;
@implementation BankAccount
+(BankAccount *) newAlloc
{
openAccounts++;
return [BankAccount alloc];
}
+(int) totalOpen
{
return openAccounts;
}
@end
</pre>
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'':
<pre>
BankAccount *account1, *account2;
account1 = [[BankAccount newAlloc] init];
account2 = [[BankAccount newAlloc] init];
</pre>
Having created the two instances of the class we can then call the totalOpen method to obtain the number of instances:
<pre>
int count = [BankAccount totalOpen];
</pre>
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:
<pre>
#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;
}
</pre>
This application can be compiled from the command line as follows:
<pre>
gcc -framework Foundation BankAccount.m main.m -o main
</pre>
When executed, we should see output generated as follows:
<pre>
2009-10-16 16:07:07.958 c[2947:10b] Number of BankAccount instances = 2
</pre>