In the Key-Value Observing Programming Guide, the section Registering for Key-Value Observing says \"Typically properties in Apple-supplied frameworks are only KVO-compliant
Based on @David DeLong's solution, this is what I came up with, and it works beautifully.
Basically, I made a category on UIWindow
. And in +load
, I (run-time) check whether [UIWindow instancesRespondToSelector:@selector(rootViewController)]
. If not, I use class_addMethod()
to dynamically add the getter & setter methods for rootViewController
. Also, I use objc_getAssociatedObject
and objc_setAssociatedObject
to get & set the rootViewController
as an instance variable of UIWindow
.
// UIWindow+Additions.h
@interface UIWindow (Additions)
@end
// UIWindow+Additions.m
#import "UIWindow+Additions.h"
#include
@implementation UIWindow (Additions)
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_4_0
// Add rootViewController getter & setter.
static UIViewController *rootViewControllerKey;
UIViewController *rootViewController3(id self, SEL _cmd);
void setRootViewController3(id self, SEL _cmd, UIViewController *newRootViewController);
UIViewController *rootViewController3(id self, SEL _cmd) {
return (UIViewController *)objc_getAssociatedObject(self, &rootViewControllerKey);
}
void setRootViewController3(id self, SEL _cmd, UIViewController *newRootViewController) {
UIViewController *rootViewController = [self performSelector:@selector(rootViewController)];
if (newRootViewController != rootViewController) {
// Remove old views before adding the new one.
for (UIView *subview in [self subviews]) {
[subview removeFromSuperview];
}
objc_setAssociatedObject(self, &rootViewControllerKey, newRootViewController,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self addSubview:newRootViewController.view];
}
}
+ (void)load {
if (![UIWindow instancesRespondToSelector:@selector(rootViewController)]) {
class_addMethod([self class], @selector(rootViewController),
(IMP)rootViewController3, "@@:");
class_addMethod([self class], @selector(setRootViewController:),
(IMP)setRootViewController3, "v@:@");
}
}
#endif
@end