最近question让我想到了类别冲突,特别是涉及UIViewControllerRotation
中的UIViewController.h
类别。此类别包括shouldAutorotateToInterfaceOrientation:
。如果有人想要覆盖这个方法(通过一个类别)并让它为每个UIViewController
运行相同的代码(因为链接的帖子试图完成),那么他们有两个类别使用相同的方法 - 我阅读导致未定义的行为。
我尝试了一下,对于iOS 4.3中基于标准视图的应用程序,旋转逻辑回落到默认的纵向旋转,有效地忽略了类别。这是在我的shouldAutorotateToInterfaceOrientation:
子类中没有定义UIViewController
方法的。有趣的是,当我确定shouldAutorotateToInterfaceOrientation:
方法并简单地调用return [super shouldAutorotateToInterfaceOrientation:]
时,就会调用该类别。所以这给我留下了两个问题:
非常感谢任何反馈!感谢。
答案 0 :(得分:8)
建议; 不要那样做!!!
您确实不希望在应用程序中的所有实例中覆盖任何给定UIKit类的所有实例的行为,原因有几个。
首先,您将以类可能无法处理的方式更改类的行为。同样,UI层次结构中无法控制的实例(通常是嵌入式复杂框架组件)的行为也会有所不同。
其次,您的实现无法知道原始实现的内部实现细节,以至于没有做出相同假设的风险。虽然你可以做一些类似混合的事情,但在这条道路上是非常脆弱的,并且将成为维护的噩梦。
答案 1 :(得分:2)
如果您有类别方法的冲突实现,那么未定义会发生什么。 UIViewController
提供了shouldAutorotateToInterfaceOrientation:
的默认实现,因此您无法通过类别附加自己的实现。
然而,您可能会劫持-[UIViewController shouldAutorotateToInterfaceOrientation:]
并插入您自己的实现。我在Hijacking with method_exchangeImplementations()中对此进行了讨论。
必须非常小心地使用它,并且取决于UIViewController
可能会发生变化的某些实现细节。所以我不建议这种方法解决大多数问题。通常,如果您想要一个“特殊的旋转视图控制器”,那就是子类化的用途。你创建了MYSpecialViewController
和你的子类。使用劫持(或动态插入对象模型的任何其他机制)将影响系统中的每个视图控制器,包括Apple提供的可能或可能不会对其做出反应的视图控制器。但对于某些问题,这是一个非常有用的解决方案。
答案 2 :(得分:0)
我也同意bbum。
但是,您可以安全地使用Class Cluster方法。通过这种方式,您将获得额外的好处:通过shouldAutorotateToInterfaceOrientation:
访问原始super
方法。
实施可能如下所示:
@interface UIViewController (MyViewController)
– (id) initMyControllerWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle;
@end
@implementation UIViewController (MyViewController)
– (id) initMyControllerWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle {
[self release];
return [[InheritedUIViewController alloc] initWithNibName:nibName bundle:nibBundle];
}
@end
通过简单继承覆盖shouldAutorotateToInterfaceOrientation:
:
@interface InheritedUIViewController: UIViewController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;
@end
@implementation InheritedUIViewController: UIViewController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// some implementation
return [super shouldAutorotateToInterfaceOrientation:interfaceOrientation]; // optional
//return yourValue;
}
@end
现在,通过分类的UIViewController
初始化initMyControllerWithNibName::
,将调用InheritedUIViewController
的{{1}}方法实现,并可以访问其原始实现。