gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Test fro overridden method


From: Richard Frith-Macdonald
Subject: Re: Test fro overridden method
Date: Sat, 30 Dec 2006 09:00:31 +0000


On 29 Dec 2006, at 01:26, Fred Kiefer wrote:

Could somebody please verify that this method does what I expect it to do? I need such a test within NSDocument. Here Apple takes special care that if somebody has implemented the old interface methods for NSDocument in
a subclass, then these methods are actually called instead of the new
interface methods.

/*
* Private helper method to check, if the method given via the selector sel
 * has been overridden in the current subclass.
 */
- (BOOL)_hasOverridden: (SEL)sel
{
// The actual signature is not important as we wont call the methods.
  IMP meth1;
  IMP meth2;

  meth1 = [self methodForSelector: sel];
  meth2 = [[NSDocument class] instanceMethodForSelector: sel];

  return (meth1 != meth2);
}

I'm not sure what you mean by 'verify' ... but unless someone has overridden any of the three methods you use, I would expect the code to return 1 if the method for _sel has been overridden, 0 otherwise.

You can bypass issues with those methods being overridden by calling the appropriate runtime functions, however if someone has overridden the methods they probably did so for a reason, and bypassing them could also cause problems. So while using the runtime directly can help, it can also (if less likely) cause problems. I would guess it is less likely to cause problems than cure them, so runtime use is probably better, but it's by no means certain.

I suppose the most efficient implementation one could do would be something like ...

BOOL
GSObjCHasOverridden(Class baseClass, NSObject *instance, SEL selector)
{
  Class instanceClass = GSObjCClass(instance);

  if (instanceClass == baseClass
|| GSGetMethod(instanceClass, selector, YES. YES) == GSGetMethod (base, selector, YES. YES))
    {
      return YES;
    }
  return NO;
}

which might be a candidate for inclusion in GSObjCRuntime.[hm]

Of course, it might be worth being able to test overriding of class methods too, depending on whether you pass an instance or a class ....

BOOL
GSObjCHasOverridden(Class baseClass, id object, SEL selector)
{
  if (GSObjCIsClass(object))
    {
      if ((Class)object == baseClass
|| GSGetMethod((Class)object, selector, NO. YES) == GSGetMethod(base, selector, NO. YES))
        {
          return YES;
        }
    }
  else
    {
      Class instanceClass = GSObjCClass(object);

      if (instanceClass == baseClass
|| GSGetMethod(instanceClass, selector, YES. YES) == GSGetMethod(base, selector, YES. YES))
        {
          return YES;
        }
    }
  return NO;
}








reply via email to

[Prev in Thread] Current Thread [Next in Thread]