ObjectiveCeeds › Objective-C: Private Methoden

Objective-C: Private Methoden

Von Manfred Kreß
Die Praxis
Seite 2 von 3



In der Praxis sieht das dann so aus: Class.h
#import 

@protocol OCClassPublicProtocol

- (void) publicMethod;
- (void) doSomethingInternal;

@end


@interface OCClass : NSObject {

}

- (void) publicMethod;
- (void) privateMethod;

- (void) doSomethingInternal;

@end
Es wird also wie üblich eine Klasse deklariert. Zusätzlich noch ein Protokoll, welches die Methoden enthält, die öffentlich sein sollen. Die Implementation von OCClass sieht dann folgendermaßen aus: Class.m
#import "Class.h"


@implementation OCClass

- (id) init
{		
	self = [super init];
	if (self != nil) {
		
		id proxy = [[NSProtocolChecker alloc] initWithTarget: self protocol: @protocol(OCClassPublicProtocol)];
		
		[self release];
		return proxy;
	}
	return nil;
}

- (void) publicMethod
{
	NSLog(@"Public");
}
- (void) privateMethod
{
	NSLog(@"Private");
}

- (void) doSomethingInternal
{
	NSLog(@"Calling Private...");
	[self privateMethod];
}

- (void) dealloc
{
	NSLog(@"goin..");
	[super dealloc];
}

@end
Anstatt wie gewohnt bei der Initialisierung self zurückzugeben, wird das Proxyobjekt zurückgegeben. Da das Proxyobjekt sein Target retained, muss self ein release geschickt werden. Wird der Proxy freigegeben (dealloc), bekommt das Target Objekt einen release und wird auch frei gegeben. Würde man das nicht tun, hätte das Target Objekt immer einen Release Count von 1 und würde nie seine dealloc triggern. publicMethod und privateMethod loggen einfach nur. doSomethingInternal ist eine Methode die der Proxy weiterreicht. Hier kann dann wieder eine Nachricht an self geschickt werden. Der Testlauf:
int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	

    id obj = [[OCClass alloc] init];
	
	
	[obj publicMethod];

	//[obj privateMethod];
	//[obj performSelector: @selector(privateMethod)];
	
	/*
	NSMethodSignature *sig = [[OCClass class] instanceMethodSignatureForSelector: @selector(privateMethod)];
	NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: sig];
	[invocation setSelector: @selector(privateMethod)];
	[invocation invokeWithTarget: obj];
	*/
	
	//objc_msgSend(obj, @selector(privateMethod));
	
	[obj doSomethingInternal];
	[obj release];
	
    [pool drain];
    return 0;
}
Die Ausgabe:
2010-05-26 12:15:00.058 proxy[43604:a0b] Public
2010-05-26 12:15:00.061 proxy[43604:a0b] Calling Private...
2010-05-26 12:15:00.061 proxy[43604:a0b] Private
2010-05-26 12:15:00.062 proxy[43604:a0b] goin..
privateMethod kann aufgerufen werden. doSomethingInternal auch, welche dann hinter dem Proxy wieder privateMethod aufrufen kann. Die diversen Versuche, die private Methode aufzurufen, sind noch auskommentiert. Aber alle Versuche, privateMethod aufzurufen scheitern mit einer Exception. Egeal ob Sie es über einen Methodenaufruf, performSelector, eine Invocation oder sogar direkt über die Runtime versuchen. OCClass bleibt hinter dem Proxy verborgen. Und der Proxy implementiert nicht eine einzige Methode selbst. Alles wird per Invocation Forwarding weitergereicht - oder auch nicht. sobald der RetainCount des Proxyobjekts auf Null geht, wird auch das eigentliche Objekt, welches vom Proxy geschützt wird, freigegeben.

« vorige Seitenächste Seite »