我正在尝试使用类别覆盖UIStoryboard方法。这是我的实施:
#import "UIStoryboard+SomeCategory.h"
#import <UIKit/UIKit.h>
@implementation UIStoryboard(SomeCategory)
-(id)instantiateInitialViewController
{
NSLog(@"SUPER CLASS: %@", [super class]); // logs "UIStoryboard"
NSLog(@"SUPER RTS : %@", [super respondsToSelector:@selector(instantiateInitialViewController)] ? @"YES" : @"NO"); // logs "YES"
return [super instantiateInitialViewController];
}
@end
当我添加:
UIViewController *viewController = [super instantiateInitialViewController]
为什么我会收到编译错误:
Receiver type 'NSObject' for instance message does not declare a method with selector 'instantiateViewController'
答案 0 :(得分:4)
如果在使用类别覆盖方法时使用super
,则将在对象的超类上调用该方法,而不是在覆盖该方法的对象上调用该方法。 您尚未创建UIStoryboard
的子类,因此super
引用NSObject
- 这会在您的错误消息中准确反映出来。
我不知道你的日志消息是怎么回事。
使用类别覆盖方法意味着您无法调用原始方法。您需要在类别中创建UIStoryboard
的子类或全新方法,并调用[self instantiateInitialViewController]
。
答案 1 :(得分:3)
您应该注意[super class]
与[self superclass]
不同。引用文档:
Objective-C提供了两个术语,可以在方法定义中用于引用执行方法自身和超级的对象。
它们在编译器搜索方法实现的方式上有所不同,在某些情况下,它们的含义也相同。
在这种情况下,您需要:
NSLog(@"SUPER CLASS: %@", [self superclass]); // logs "NSObject"
检查一个对象的超类类,你需要一个UIStoryBoard子类,而不是一个类,才能使用:
return [super instantiateInitialViewController];
为什么[super class]
没有记录您期望的另一个主题。如果你有兴趣,这篇文章What is a meta-class in Objective-C?是一个很好的起点。
答案 2 :(得分:1)
你需要使用方法调配。有关如何将其用于您的目的的详细说明:http://b2cloud.com.au/how-to-guides/method-swizzling-to-override-in-a-category
答案 3 :(得分:0)
如果你真的想从UIViewController调用该方法,你的类别应该是:
@implementation UIViewController(SomeCategory)
即使这样,它也会调用你的UIViewController的super,所以它仍然无效。您还需要执行以下操作:
UIViewController *viewController = [self instantiateInitialViewController]