1

我正在尝试向 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];
    }
}

任何关于我可以实现这一点的方法的想法都将不胜感激。谢谢!

更新:通过更多的搜索,这似乎可以通过一种叫做 swizzling 的东西来完成。然而,目前这方面的尝试尚未成功。任何关于使用 swizzling 来实现这一目标的技术建议也会有所帮助。

4

2 回答 2

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

请注意,这只会 swizzle -description,尽管NSLog可能会调用其他方法,例如NSArray's–descriptionWithLocale:

于 2013-07-11T05:14:59.617 回答
-1

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

点击这里阅读更多!

于 2013-04-19T18:20:38.953 回答