调用类别的未重写方法

时间:2013-04-19 18:08:43

标签: objective-c override objective-c-category

我正在尝试向NSObject的描述方法添加一个条件,其中响应可选协议(PrettyPrinter)中的方法的任何对象将打印来自协议方法的结果而不是正常的NSObject描述。但是,如果正在打印的对象没有响应协议,那么描述应该返回它通常的方式。

我目前尝试这样做涉及在NSObject上编写一个包含此协议和重写描述方法的类别。但是,我没有意识到调用类别的未覆盖方法的任何方法。

-(NSString*)description
{
    if ([self respondsToSelector:@selector(prettyPrinter)]) {
        return self.prettyPrinter;
    }else{
        // Would Like to return normal description if does not respond to selector. But
        // can not call super description due to being a category instead of a subclass
        return [super description];
    }
}

关于如何实现这一目标的任何想法将不胜感激。谢谢!

更新: 通过更多的搜索,似乎可以通过称为混合的东西来完成。但是,目前对此的尝试尚未成功。任何关于使用调配来实现这一目标的技巧的建议也会有所帮助。

2 个答案:

答案 0 :(得分:2)

正如您所指出的,这可以通过方法调配来实现。运行时具有交换两种方法实现的功能。

#import <objc/runtime.h>

@interface NSObject (PrettyPrinter)
- (NSString*) prettyPrinter;
@end

@implementation NSObject (PrettyPrinter)

// This is called when the category is being added
+ (void) load {
  Method method1 = class_getInstanceMethod(self, @selector(description));
  Method method2 = class_getInstanceMethod(self, @selector(swizzledDescription));

  // this is what switches the two methods
  method_exchangeImplementations(method1, method2);
}

// This is what will be executed in place of -description
- (NSString*) swizzledDescription {
  if( [self respondsToSelector:@selector(prettyPrinter)] ) {
    return [self prettyPrinter];
  }
  else {
    return [self swizzledDescription];
    // The above is not a recursive call, remember the implementation has
    //   been exchanged, this will really execute -description
  }
}

- (NSString*) prettyPrinter {
  return @"swizzled description";
}

@end

可以删除-prettyPrinter方法,在这种情况下,NSLog将返回-description定义的值。

请注意,这只会调动-description,但NSLog可能会调用其他方法,例如NSArray的{​​{1}}

答案 1 :(得分:-1)

如果类别覆盖了类别类中存在的方法,则无法调用原始实现。

Click Here To Read More!