Retain and Release, and Object Creation
Objects in Objective-C maintain a counter to manage how many object point to the object in question. This counter modified by two methods, retain
and release
, and can be accessed directly by the retainCount
method.
Each call to [object retain];
increments this counter, and each call to [object release];
decrements it. The retain/release counter starts at 1. When an object's count drop to 0, it deallocates itself. In Memory Management documentation, you'll find this behavior referred to as Reference Counting.
When an object deallocates itself, it uses its dealloc
method. This method is comparable to a destructor in C++. Like C++, dealloc
takes no arguments, and has no return value.
To create an object, you've probably noticed the [[object alloc] init];
sequence used. This uses two methods, alloc
and init
. alloc
simply allocates memory. It is essentially the same as malloc()
in C. init
is used to initialize objects to a usable state. This is the job of a constructor in C++.
Writing our own init
and dealloc
methods requires a bit of work for things to work right. I'll present an example with both, and then explain the various parts and pieces.
#import <Foundation/Foundation.h>
@interface myObject: NSObject
{
@private
int count;
int refs;
}
-(id)init;
-(void)dealloc;
-(int)getCount;
-(void)incCount;
@end
@implementation myObject
-(id)init
{
self = [super init];
count = 0;
refs = 0;
printf("Running myObject's init method\n");
return self;
}
-(void)dealloc
{
printf("Running myObject's dealloc method\n");
[super dealloc];
}
-(int)getCount
{
return count;
}
-(void)incCount
{
++count;
}
@end
int main()
{
myObject *obj = [[myObject alloc] init];
printf("Object's count: %i\n",[obj getCount]);
[obj incCount];
[obj incCount];
[obj incCount];
printf("Object's count: %i\n",[obj getCount]);
[obj release];
return 0;
}
In this example, we have a simple class called
myObject
. This object implements a working init
and dealloc
, and little else.First, an
init
method's declaration looks like this: -(id)init;
. This means the return type is id
, which is certainly not a standard C type. This type is similar to void*
in C or C++. This basically means that we'll be returning a pointer to ourselves when the init
method returns.In the implementation of
init
we have some more magic. The first is self = [super init];
. This line has two ideas; self
and super
. self
is basically *this
in C++. It's a reference to the object in question. So we're setting our object's reference to [super init]
. This, unsurprisingly, uses super
, another built-in variable that points to our class's parent class. Setting self
to our object's parent's init
method is required for proper inheritance.Following all that stuff,
init
finishes with return self;
. This returns a reference to our object so that the caller (main
in this case) can access it.In the
dealloc
method, we have a similar expression, [super dealloc];
. This method does any necessary clean-up of our object using our class's parent's dealloc
method. We are still responsible for any clean up we need to do ourselves (none in this example), but that's it.Using
init
, dealloc
, retain
, and release
allow us to start creating real complex classes, and do some basic memory management. There's still much more available in terms of memory management though, in the form of NSAutoReleasePool
s, but those are reserved for a future entry.In case you were curious, the above program's output looks like this:
Running myObject's init method
Object's count: 0
Object's count: 3
Running myObject's dealloc method
1 comment:
supreme clothing
adidas yeezy
supreme clothing
moncler
outlet golden goose
kobe basketball shoes
adidas yeezy
nike lebron 15
curry 7 shoes
supreme clothing
Post a Comment