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: Greg Parker <email@hidden>
- Date: Fri, 30 Jul 2004 14:24:42 -0700
On Jul 30, 2004, at 1:08 PM, Jim Correia wrote:
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.
Thus demonstrating why using +poseAsClass: is dangerous when instances
of the original class may exist. Bad framework, no biscuit.
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.)
Yes. This is correct though non-intuitive behavior. The problem is that
[NSView class] returns a different result after an impostor poses as
NSView.
[NSView class]; // returns original NSView class
[PoserView poseAsClass:[NSView class]];
[NSView class]; // returns impostor NSView
class, a subclass of original NSView
Thus you get the following behavior:
aView = [NSView new]; // aView is an instance of
original NSView
[aView isKindOfClass:[NSView class]]; // returns YES, because aView
is an NSView
[PoserView poseAsClass:[NSView class]];
[aView isKindOfClass:[NSView class]]; // returns NO, because [NSView
class] is the impostor but [aView class] is the original
However, only the replaced class (NSView in this case) is affected. If
you're dealing with an instance of a subclass of NSView, nothing
changes:
aView = [CustomView new]; // CustomView is a subclass of
NSView
[aView isKindOfClass:[NSView class]]; // returns YES, because aView
isa CustomView, which is an NSView subclass
[PoserView poseAsClass:[NSView class]];
[aView isKindOfClass:[NSView class]]; // returns YES, because
CustomView is a subclass of the original NSView and the impostor NSView
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.
There are potential ripple effects, but you may or may not run across
problems because of them. The problem is that your implementation of
-isKindOfClass: is lying; after posing, your old instances really
aren't instances of the new NSView class. Some code might be confused
because your old instances claim to be NSView but don't act like other
NSViews, but such code may be rare.
A second workaround may be to use a custom subclass of NSView for your
instances, and never actually instantiate NSView itself. The extra
level of subclassing would protect you from any ill effects of posing.
Sample Code:
[snip]
I get "is right kind" for all three tests. However, if you tried
check_obj(foo) again after the pose, you would get "is NOT right kind".
Also, if you added a subclass of Foo that wasn't involved in the
posing, it would be "is right kind" both before and after.
--
Greg Parker email@hidden Runtime Wrangler
_______________________________________________
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.