我有一个ViewController创建一个UIView的实例,然后我用这个实例注册一个观察者
logoAnimation = [[MainLogoAnimation alloc] init];
[logoAnimation addObserver:self forKeyPath:@"patrocinioDidLoad" options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) context:nil];
Run Code Online (Sandbox Code Playgroud)
然后,在同一个文件中,我有:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"%@ \n %@ \n %@ \n ",keyPath,object,change);
}
Run Code Online (Sandbox Code Playgroud)
但是,虽然我已经检查并仔细检查了logoAnimation.patrocinioDidLoad是否发生了变化,但观察到的值仍未被调用...
我错过了什么吗?
谢谢您的帮助!
安东尼奥
在Key-Value Observing Programming Guide中,注册键值观察部分说:"Apple提供的框架中的典型属性只有符合KVO标准才会被记录." 但是,我没有在文档中找到任何记录为KVO兼容的属性.你能指点一下吗?
具体来说,我想知道,如果@property(nonatomic,retain) UIViewController *rootViewController的UIWindow是国际志愿者组织兼容.原因是我正在为iOS <4 添加rootViewController属性,UIWindow并想知道我是否应该使其符合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]; …Run Code Online (Sandbox Code Playgroud) 我正在使用与xCode7 Beta 2兼容的代码.刚刚获得Beta 3,现在我遇到了这个似乎是xCode错误的问题?
对于我的一个公共课......
override public func observeValueForKeyPath...
Run Code Online (Sandbox Code Playgroud)
错误:方法不会覆盖其超类中的任何方法
所以我拿出"覆盖":
public func observeValueForKeyPath
Run Code Online (Sandbox Code Playgroud)
错误:方法与具有相同Objective-C选择器的超类NSObject中的方法冲突哈哈!我被第一个错误骗了.不会编译任何一种方式.
有什么帮助吗?
我正在使用KVC/KVO为大学项目创建自定义绑定实现(它需要自定义,因为我想做的事情超出了绑定可以做的事情,包括在iOS上运行).
我有一个'绑定控制器',它在一个对象的多个键上注册KVO通知(使用addObserver:forKeyPath:options:context :),我确实收到了通知.但是,我收到了每个更改的两个通知.我有一个解决方法的想法,但我宁愿弄清楚为什么会发生这种情况并纠正它!
有没有人有任何想法为什么会这样?我确定我一次只注册了每个通知,并且取消注册一次会导致两个通知都停止.
谢谢.
编辑:
我有一些代码请求,所以我会把它放进去.目前有点粗糙,它基本上仍然是一个概念证明,所以请耐心等待.
这是我观察的属性之一(我知道它有点奇怪,但这个类本质上暴露了NSManagedObject的某些属性作为自身的属性):
- (void)setName:(NSString *)name
{
[self willChangeValueForKey:@"name"];
[contact setFirstName:name];
[self didChangeValueForKey:@"name"];
}
Run Code Online (Sandbox Code Playgroud)
这是我用来观察该属性的代码(确认只运行一次,并且只在一个地方运行):
[viewModel addObserver:self
forKeyPath:@"name"
options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial)
context:viewController];
Run Code Online (Sandbox Code Playgroud)
之后的任何调用都会改变该属性,例如:
viewModel.name = @"Joe";
[viewModel setName: @"Joe"];
[viewModel setValue: @"Joe" forKey: @"name"];
Run Code Online (Sandbox Code Playgroud)
会导致该方法:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
Run Code Online (Sandbox Code Playgroud)
要被调用两次,每次使用相同的参数.
在向核心数据模型添加2个附加字段后,我遇到了以下错误.
CarPark_CarPark_ was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object.
Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger.
Here's the current observation info:
<NSKeyValueObservationInfo 0x1b6510> (
<NSKeyValueObservance 0x19b210: Observer: 0x1a8cf0, Key path: coordinate,
Options: <New: NO, Old: NO, Prior: YES> Context: 0x0, Property: 0x1b7e00>
)
Run Code Online (Sandbox Code Playgroud)
我对下一步做什么有点迷茫.任何有关这方面的指导将非常感谢!请让我知道还需要哪些其他信息.
是否可以观察字典中的特定键?如果是这样我该怎么办?
我很高兴使用Key Value Observing(KVO),以及如何注册接收财产变更通知:
[account addObserver:inspector
forKeyPath:@"openingBalance"
options:NSKeyValueObservingOptionNew
context:NULL];
Run Code Online (Sandbox Code Playgroud)
但是,如果我想观察帐户对象的所有属性的更改,我该如何实现?我是否必须注册每个房产的通知?
我正在重写应用程序的一部分,并找到了这段代码:
fileprivate let defaults = UserDefaults.standard
func storeValue(_ value: AnyObject, forKey key:String) {
defaults.set(value, forKey: key)
defaults.synchronize()
NotificationCenter.default.post(name: Notification.Name(rawValue: "persistanceServiceValueChangedNotification"), object: key)
}
func getValueForKey(_ key:String, defaultValue:AnyObject? = nil) -> AnyObject? {
return defaults.object(forKey: key) as AnyObject? ?? defaultValue
}
Run Code Online (Sandbox Code Playgroud)
当CMD点击该行时,defaults.synchronize()我看到synchronize计划已弃用.这是在代码中写的:
/*!
-synchronize is deprecated and will be marked with the NS_DEPRECATED macro in a future release.
-synchronize blocks the calling thread until all in-progress set operations have completed. This is no longer necessary. Replacements for …Run Code Online (Sandbox Code Playgroud) 在我的UIScrollView子类中,我正在观察帧更改:
[self addObserver:self forKeyPath:@"frame" options:0 context:NULL];
Run Code Online (Sandbox Code Playgroud)
我的observeValueForKeyPath:ofObject:change:context:实现如下:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (object == self && [keyPath isEqualToString:@"frame"]) {
[self adjustSizeAndScale];
}
if ([UIScrollView instancesRespondToSelector:@selector(observeValueForKeyPath:ofObject:change:context:)]) {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; // Exception
}
}
Run Code Online (Sandbox Code Playgroud)
但是这个代码我得到了异常:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '<WLImageScrollView: 0x733a440; baseClass = UIScrollView; frame = (0 0; 320 416); clipsToBounds = YES; layer = <CALayer: 0x7346500>; contentOffset: {0, 0}>: An -observeValueForKeyPath:ofObject:change:context: message was received but not …Run Code Online (Sandbox Code Playgroud) 我在Apple的一些示例代码中发现了这个构造,用于处理键值观察.添加观察者时,可以添加可以唯一标识KVO调用的上下文(以void*变量的形式) - 如果您希望多个KVO调用触发相同的操作,则特别有用,因为单个上下文可以避免使用一堆链式或语句来检查所有可能性.这是用于声明用于上下文的变量的行:
static void *aContext = &aContext;
Run Code Online (Sandbox Code Playgroud)
它基本上声明了一个引用自身的aContext,为自己分配了自己的内存位置 - 这是一个为KVO上下文创建唯一标识符的绝妙技巧.除了细节之外,我很好奇这究竟叫做什么(自我指定?圆形指针?还有什么?)以及除了KVO之外它还有什么用处.我尝试使用谷歌搜索不同的东西,但我无法想出任何完全相同的东西,缺乏适当的术语.:)
我肯定会定期使用这个技巧,因为它减少了KVO处理所需的if语句数量,这使得它更加优雅.
ios ×6
objective-c ×6
cocoa ×2
macos ×2
swift ×2
c ×1
cocoa-touch ×1
core-data ×1
foundation ×1
ios4 ×1
iphone ×1