Mailing Lists: Apple Mailing Lists
Image of Mac OS face in stamp
finding protocols for a given class
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

finding protocols for a given class



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello All,

I am writing an app a little bit like class-dump, as an educational exercise in (a) Mac OS X Cocoa programming and (b) to learn what things are actually available in the Cocoa API - it's an interesting task.

I've struck a problem however, with the discovery of formal protocols. Quite likely, I am doing something silly.

My understanding of the obj-c meta information is such:
- - a class that implements a formal protocol, by declaring it in the header and implementing that protocols methods - should have a Class structure representing that [implemented] protocol in it's Class- >protocols list.


e.g.
@interface MyClass : NSObject < TheProtocol >
...

- - the obj-c 'Class' structure contains a list of implemented [formal] protocols, reachable by traversing the Class->protocols pointer.
- - protocols are simply 'struct objc_object' structures, i.e. classes (once one traverses the objc_object->isa relationship)


My problem is that all the protocols I am traversing are called 'Protocol', and I can't seem to find the test protocol that I've implemented to check this.

Here's my logic:

+ (void) iterateProtocolsForClass:(Class)cls intoArray: (NSMutableArray *)protocolArray
{
struct objc_protocol_list *prot_list = cls->protocols;

while(prot_list != 0)
{
int index;
for(index = 0; index < prot_list->count; ++index)
{
id prot = *(prot_list->list + index);
Class class_of_protocol = [prot class];

NSString *protName = [NSString stringWithCString:class_of_protocol- >name];

// does it already exist in the protocol cache?
// protocolCache is an NSMutableDictionary, declared elsewhere...
MetaModel_Class* protocolMeta =
[protocolCache objectForKey:protName];

if(protocolMeta == nil)
{
NSLog(@"caching protocol named: %@", protName);
protocolMeta = [[MetaModel_Class alloc] initWithClassName:class_of_protocol->name];
[protocolCache setObject:protocolMeta forKey:protName];
}

[protocolArray addObject:protocolMeta];
}


		prot_list = prot_list->next;
	}
}

I call it like this:

+ (NSArray *) protocolsForClassNamed:(const char *)className
{
// there is a shared list of protocols, which are simply MetaModel_Class
// instances
initProtocolCache();

NSMutableArray *protocolsArray = [[NSMutableArray alloc] init];
[protocolsArray autorelease];

Class theClass = objc_getClass(className);
while(theClass != 0)
{
// don't recurse forever...
bool isNSObject = theClass == theClass->super_class;


		[self iterateProtocolsForClass:theClass intoArray:protocolsArray];

		theClass = theClass->super_class;
		if(isNSObject)
			break;
	}

	return protocolsArray;
}


So, when I compile this into the rest of my app and start it up, I call it for each and every class that is being discovered at runtime - - and I see the following output:
[Session started at 2006-01-21 09:30:03 +0100.]
2006-01-21 09:30:04.823 SymbolExplorer[1557] caching protocol named: Protocol
2006-01-21 09:30:08.149 SymbolExplorer[1557] added 1502 items in this scan
2006-01-21 09:30:08.155 SymbolExplorer[1557] added 0 items in this scan


Which to me, is just plain wrong.

I've traced this through in the debugger, and can't see what I am doing incorrectly. Anyone got an idea I can try? Is there a compiler switch to use? (I'm using gcc 4 - but switching back to 3.3 makes no difference either).

Thanks everyone, any comments and discussion appreciated.

Take care,

john clayton
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Darwin)

iD8DBQFD0fm1p5OOqU+VYFgRAq04AKCHFHWkqGmzXpgkoScs5dnrugVXDACggmO8
hh2fxBzFGGXnorIsc6QMSPA=
=A30c
-----END PGP SIGNATURE-----
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Objc-language mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden




Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2011 Apple Inc. All rights reserved.