在Key-Value Observing Programming Guide , 第 Registering for Key-Value Observing说“通常情况下,Apple 提供的框架中的属性只有在被记录为这样的情况下才符合 KVO。”但是,我没有在文档中找到任何被记录为符合 KVO 的属性。你能给我指出一些吗?
具体来说,我想知道 UIWindow
的 @property(nonatomic,retain) UIViewController *rootViewController
是否符合 KVO。原因是我将 rootViewController
属性添加到 UIWindow
for iOS < 4 并想知道我是否应该使其符合 KVO。
@interface UIWindow (Additions)
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_4_0
@property (nonatomic, retain) UIViewController *rootViewController;
#endif;
@end
@implementation UIWindow (Additions)
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_4_0
@dynamic rootViewController;
- (void)setRootViewController:(UIViewController *)newRootViewController {
if (newRootViewController != _rootViewController) {
// Remove old views before adding the new one.
for (UIView *subview in [self subviews]) {
[subview removeFromSuperview];
}
[_rootViewController release];
_rootViewController = newRootViewController;
[_rootViewController retain];
[self addSubview:_rootViewController.view];
}
}
#endif
@end
最佳答案
简短的回答:没有。
长答案:UIKit 中的任何内容都不能保证符合 KVO。如果你碰巧发现 KVO-ing 一个属性有效,感激不尽,这是无意的。另外:要小心。它很可能在未来破裂。
如果您发现这是您需要的东西,请file an enhancement request .
关于您的实际代码,它存在固有缺陷。 不要尝试以这种方式将“rootViewController”setter 添加到UIWindow
。当您在 iOS 4 上编译代码但有人在 iOS 5 设备上运行它时,它会中断。因为您使用 4.x SDK 进行编译,所以 #if
语句的计算结果为真,这意味着您的类别方法 smasher 将包含在二进制文件中。但是,当您在 iOS 5 设备上运行它时,您现在会遇到方法冲突,因为 UIWindow
上的两个方法将具有相同的方法签名,并且不能保证将使用哪一个。
不要像这样搞砸框架。如果你必须有这个,使用一个子类。这就是子类存在的原因。
你的子类看起来像这样:
@interface CustomWindow : UIWindow
@property (nonatomic, retain) UIViewController *rootViewController;
@end
@implementation CustomWindow : UIWindow
static BOOL UIWindowHasRootViewController = NO;
@dynamic rootViewController;
- (void)_findRootViewControllerMethod {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
IMP uiwindowMethod = [UIWindow instanceMethodForSelector:@selector(setRootViewController:)];
IMP customWindowMethod = [CustomWindow instanceMethodForSelector:@selector(setRootViewController:)];
UIWindowHasRootViewController = (uiwindowMethod != NULL && uiwindowMethod != customWindowMethod);
});
}
- (UIViewController *)rootViewController {
[self _findRootViewControllerMethod];
if (UIWindowHasRootViewController) {
// this will be a compile error unless you forward declare the property
// i'll leave as an exercise to the reader ;)
return [super rootViewController];
}
// return the one here on your subclass
}
- (void)setRootViewController:(UIViewController *)rootViewController {
[self _findRootViewControllerMethod];
if (UIWindowHasRootViewController) {
// this will be a compile error unless you forward declare the property
// i'll leave as an exercise to the reader ;)
[super setRootViewController:rootViewController];
} else {
// set the one here on your subclass
}
}
Caveat Implementor:我在浏览器窗口中输入了这个
关于objective-c - iOS:我如何知道一个属性是否符合 KVO 标准?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6612523/