Re: What does it mean when po puts % before class name?
Re: What does it mean when po puts % before class name?
- Subject: Re: What does it mean when po puts % before class name?
- From: Jim Correia <email@hidden>
- Date: Fri, 30 Jul 2004 16:08:13 -0400
Please excuse the long-winded response...
On Jul 30, 2004, at 3:08 PM, Greg Parker wrote:
I'm debugging a uncaught exception, and I'm trying to examine objects
just before the point of failure. What does it mean when a % appears
as
in the class name as a result of po?
(gdb) po $r5
<%NSView: 0xcca4f40>
This means some code somewhere has used +poseAsClass: to replace
NSView with a custom implementation. The impostor class takes the name
"NSView", and the priginal NSView gets the name "%NSView" and becomes
the impostor's superclass.
Most likely, the object you're looking at was allocated before posing
occurred. Existing instances of the original class are not re-assigned
to the impostor class after posing, but new instances created
afterwards will be of the impostor class.
Old class hierarchy:
"NSObject"
|
|
"NSView" (original)
|
|
"MyImpostor" (impostor)
Class hierarchy after [MyImpostor poseAsClass:NSView]:
"NSObject"
|
|
"%NSView" (original)
/ \
/ \
"NSView" (impostor) "MyImpostor" (copy of impostor)
Thanks Greg. That got me to the point that I could debug the problem. A
nameless Apple framework (nameless to protect the guilty :-) - I'll
file a bug) has a private class which does a poseAsClass: [NSView
class] the first time it is used - which happens much after application
startup. Later on when I set my accessory view on the font panel,
NSView is sent an addSubview: message. It checks isKindOfClass: [NSView
class] and then raises an exception.
This raises two questions.
1) Is isKindOfClass supposed to return NO in that instance? (See sample
code at end of message.)
2) Since this is a private class in an Apple framework, after I file a
bug, is it a reasonable workaround to just add a category to NSView
which does the following?
@implementation NSView(BugWorkaround)
- (BOOL)isKindOfClass:(Class)aClass
{
if (aClass == [NSView class])
{
return YES;
}
return [super isKindOfClass: aClass];
}
@end
It seems to work, but I don't know if I will cause any ripple effects
by doing so.
Thanks,
Jim
Sample Code:
#import <Foundation/Foundation.h>
@interface Foo : NSObject
{
}
@end
@implementation Foo
@end
@interface Bar : Foo
{
}
@end
@implementation Bar
@end
static void check_obj(id obj)
{
if ([obj isKindOfClass: [Foo class]])
{
NSLog(@"is right kind %@", obj);
}
else
{
NSLog(@"IS NOT right kind%@", obj);
}
}
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Foo *foo = [[Foo alloc] init];
Foo *foo2 = nil;
Bar *bar = nil;
check_obj(foo);
[Bar poseAsClass: [Foo class]];
foo2 = [[Foo alloc] init];
bar = [[Bar alloc] init];
check_obj(foo2);
check_obj(bar);
[pool release];
return 0;
}
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.