ObjectiveCeeds › Objective-C: Speicherverwaltung zu Fuß

Objective-C: Speicherverwaltung zu Fuß

Von Manfred Kreß
Ein Root Objekt
Seite 2 von 6



Statt Speicher direkt frei zu geben, wäre es doch sinnvoll, wenn man mitzählen würde, wie viele andere Objekte noch einen Zeiger auf ein Objekt haben. Jedes Objekt hat einen Zähler, einen sog. „Retain Count“, den es abspeichert. Solange ich nun ein Objekt brauche, erhöhe ich diesen Retain Count um eins, umgekehrt erniedrige ich den Zähler, wenn ich das Objekt nicht mehr brauche. Ist ein Retain Count bei Null angelangt, wird der Speicher freigegeben. Das könnte man z.B. in einer Tabelle tun, sozusagen Buch führen über die Pointer. Es würde allerdings ehr dem Paradigma der objektorientierten Programmierung entsprechen, wenn jede Instanz selbst mitzählen würde und sich bei Bedarf auch selbst frei gibt. Wir wollen nun Schritt für Schritt so ein „Life Circle Management“ entwickeln. Da alle Klassen bzw. Objekte dieses Verhalten beherrschen sollen, wäre es sinnvoll es in einer Root Klasse zu implementieren. Zunächst entwickeln wir also eine eigene Root Klasse, auf der wir alle weiteren Klassen aufbauen. Wir nennen sie OCObject. Die Klasse OCObject erweitert die eigentliche Root Klasse Object. OCObject muss folgende Merkmale aufweisen:
  • Einen Zähler, retainCount
  • Eine Methode mit der es mitgeteilt bekommt, das es noch benötigt wird - retain.
  • Eine Methode mit der es mitgeteilt bekommt, das es nich weiter benötigt wird - release.
  • Sobald der Zähler auf Null ist, muss das Objekt seinen Speicher freigeben.
  • Es sollte eine Methode geben, in der das Objekt „aufräumt“, bevor es sich selbst frei gibt. D.h. vor allem, alle Objekte auf die es einen Zeiger hat wiederum selbst zu „releasen“ - nicht verwechseln mit Speicher frei geben!. Wir nennen sie cleanup. Sie ist primär dazu gedacht, um von Subklassen überschrieben zu werden.
  • Bei der Initialisierung soll der retainCount einen Wert von 1 haben.
Die Methode cleanup wurde nicht dealloc genannt, da Xcode (gcc) Warnungen ausgibt wenn dealloc "nicht richtig" implementiert wird. Ein Apple Feature... In einem Objective C Interface modelliert:
//
//  OCObject.h
//  RetainCount
//
#import <stdio.h>
#import <stdlib.h>
#import <objc/Object.h>

@interface OCObject : Object {

	// stores the retain count of an Object
	int _OCRetainCount;
}
/*
	returns the RC of the object
*/
- (int) retainCount;

/*
	retains the reciever
*/
- (void) retain;

/*
	releases the reciever. If the RC becomes 0, cleanup is called
*/
- (void) release;

/*
	releases of ivars go here. override this with your own cleanup
	allways send [super cleanup]; in your own implementation.
	Finally cleanup calls the free method to deallocate
        its own memory
*/
- (void) cleanup;

@end
Die Implementation:
//
//  OCObject.m
//  RetainCount
//
//  Created by Manfred Kress on 05.09.08.
//  Copyright 2008 ObjectiveCeeds. All rights reserved.
//

#import "OCObject.h"

@implementation OCObject

- (int)retainCount
{
	return _OCRetainCount;
}

- (id) init
{
	self = [super init];
	if (self != nil) {

		_OCRetainCount = 1;
	}
	return self;
}

- (void) retain
{
	_OCRetainCount++;
}

- (void) release
{
	_OCRetainCount--;

	if (_OCRetainCount == 0)
	{
		[self cleanup];
	}
}

- (void) cleanup
{
	printf("cleanup\n");
	[self free];
}

@end
Wir haben nun eine Klasse die free über den Retaincount triggert. Nun sollen noch zwei weitere Klassen auf Basis von BAObject entwickelt werden, die dieses Verhalten nutzen. Die erste Klasse speichert einen c-string und übernimmt die dynamische Speicherverwaltung - OCString. Die zweite Klasse speichert ein Array von Objective-C Objekten, also id Typen - OCArray.

« vorige Seitenächste Seite »