我正在尝试向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];
}
}
关于如何实现这一目标的任何想法将不胜感激。谢谢!
更新: 通过更多的搜索,似乎可以通过称为混合的东西来完成。但是,目前对此的尝试尚未成功。任何关于使用调配来实现这一目标的技巧的建议也会有所帮助。
答案 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)
如果类别覆盖了类别类中存在的方法,则无法调用原始实现。