我一直试图找到一个例子,但我所看到的并不适用于我的情况.
什么是以下代码的等价物:
object.addObserver(self, forKeyPath: "keyPath", options: [.new], context: nil)
override public func observeValue(
forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
}
Run Code Online (Sandbox Code Playgroud)
上面的代码有效,但我从SwiftLink收到警告:
使用Swift 3.2或更高版本时,首选基于新块的KVO API和键路径.
如果你能指出我正确的方向,我感激不尽.
虽然我有一些想法可以使用,但确切的用法仍然不清楚.有人能解释一下......?谢谢.
我想做一个简单的KVO例子,但我遇到了问题.
这是我的*.m文件:
#import "KVO_ViewController.h"
@interface KVO_ViewController ()
@property NSUInteger number;
@end
@implementation KVO_ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self addObserver:self forKeyPath:@"number" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)incNumber:(id)sender
{
_number++;
NSLog(@"%d", _number);
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"From KVO");
if([keyPath isEqualToString:@"number"])
{
id oldC = [change objectForKey:NSKeyValueChangeOldKey];
id …Run Code Online (Sandbox Code Playgroud) 我试图在我的一个类中使用键值观察.我在init方法中注册观察者并在dealloc中删除/注销它们,但是我得到了以下错误,这似乎是在调用dealloc方法之前发生的,根据我的调试打印.
正在释放类TekkPoint的实例0x583870,而键值观察者仍在其中注册.观察信息被泄露,甚至可能被错误地附加到其他物体上.在NSKVODeallocateBreak上设置断点以在调试器中停止.这是当前的观察信息:(上下文:0x0,属性:0x536400>上下文:0x0,属性:0x55aba0>)
有什么特别的方法可以删除观察者吗?或者也许是我应该删除它们的特定地方?
根据这个问题,我正在做正确的事情,但为什么我会收到此错误消息?
这是我的dealloc例程:
- (void)dealloc {
// Remove all observers.
for (NSString *path in [TekkPoint observedPaths]) {
[self removeObserver:[option_ tChart]
forKeyPath:path];
}
[description_ release];
[weight_ release];
[super dealloc];
}
Run Code Online (Sandbox Code Playgroud)
需要注意的一点是,我的实现可能很奇怪,我正在向观察者添加和删除观察者,这是否会导致我的问题?
objective-c key-value-observing cocoa-bindings observer-pattern
我对KVO比较陌生,所以我很有可能违反了一些基本规则.我正在使用核心数据.
我的应用程序崩溃了以下消息:我无法理解的是为什么CGImage参与观察在MeasurementPointer对象上设置的值.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '<CGImage 0x276fc0>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: measurementDescriptor
Observed object: <MeasurementPointer: 0x8201640> (entity: MeasurementPointer; id: 0x8200410 <x-coredata://EBEE0687-D67D-4B03-8C95-F4C60CFDC20F/MeasurementPointer/p75> ; data: {
measurementDescriptor = "0x260fd0 <x-coredata://EBEE0687-D67D-4B03-8C95-F4C60CFDC20F/MeasurementDescriptor/p22>";
})
Change: {
kind = 1;
new = "<MeasurementDescriptor: 0x262530> (entity: MeasurementDescriptor; id: 0x260fd0 <x-coredata://EBEE0687-D67D-4B03-8C95-F4C60CFDC20F/MeasurementDescriptor/p22> ; data: {\n measurementName = Temperature;\n measurementUnits = \"\\U00b0C\";\n sortString = nil;\n})";
}
Context: 0x0'
*** Call stack at first throw:
(
0 CoreFoundation 0x30897ed3 …Run Code Online (Sandbox Code Playgroud) 在以下方法中使用context参数有什么用于注册键值通知.文档只是将其表示为任意数据集.
addObserver:self forKeyPath:@"selectedIndex" options:NSKeyValueObservingOptionNew context:nil
Run Code Online (Sandbox Code Playgroud)
有人可以说清楚它背后的目的是什么......
如果我存储这样的观察者:
let observer: NSKeyValueObservation = foo.observe(\.value, options: [.new]) { (foo, change) in
print(change.newValue)
}
Run Code Online (Sandbox Code Playgroud)
observer一旦我不再需要它,如何删除/禁用/清除?
我的foo实例没有remove接收NSKeyValueObservation实例的任何类似方法,它observer本身也没有任何remove类似的实例.
是否有一个方法返回符合NSKeyValueCoding协议的对象的所有键?
沿着这条线的东西[object getPropertyKeys]将返回NSString对象的NSArray.它适用于任何符合KVC标准的对象.这种方法存在吗?到目前为止,我还没有找到任何搜索Apple文档的内容.
谢谢,G.
cocoa properties introspection objective-c key-value-observing
我正在寻找一种在可见视图层次结构中添加或删除通用UIView时收到通知的方法.在这种情况下,KVO看起来像是完美的东西,但观察视图窗口或超视图属性的变化并没有做任何事情.对frame或backgroundColor等属性的更改按预期工作但更改为与视图层次结构相关的属性似乎从未调用observeValueForKeyPath.
我通过调用automaticNotifiesObserversForKey来检查UIView是否支持这些属性的KVO,UIView为两者报告了YES,让我不知所措.所以我的问题是:
1)是否有办法使用KVO通知与视图层次结构中添加/删除视图相关的事件?
2)如果没有,是否有其他方式可以通知不涉及UIView子类的事件?
在Objective-C中,我通常会使用这样的东西:
static NSString *kViewTransformChanged = @"view transform changed";
// or
static const void *kViewTransformChanged = &kViewTransformChanged;
[clearContentView addObserver:self
forKeyPath:@"transform"
options:NSKeyValueObservingOptionNew
context:&kViewTransformChanged];
Run Code Online (Sandbox Code Playgroud)
我有两个重载方法可供选择,为KVO添加一个观察者,唯一的区别是context参数:
clearContentView.addObserver(observer: NSObject?, forKeyPath: String?, options: NSKeyValueObservingOptions, context: CMutableVoidPointer)
clearContentView.addObserver(observer: NSObject?, forKeyPath: String?, options: NSKeyValueObservingOptions, kvoContext: KVOContext)
Run Code Online (Sandbox Code Playgroud)
由于Swift不使用指针,我不确定如何取消引用指针以使用第一种方法.
如果我创建自己的KVOContext常量以便与第二种方法一起使用,我最终会问它:
let test:KVOContext = KVOContext.fromVoidContext(context: CMutableVoidPointer)
Run Code Online (Sandbox Code Playgroud)
编辑:CMutableVoidPointer和KVOContext有什么区别?有人可以给我一个例子,说明如何使用它们以及何时使用它们?
编辑#2:苹果公司的开发人员刚刚将这个发布到了论坛:KVOContext正在消失; 使用全局引用作为您的上下文是现在的方法.
objective-c ×4
swift ×3
cocoa ×2
ios ×2
iphone ×2
swift4 ×2
cocoa-touch ×1
keypaths ×1
nsexception ×1
pointers ×1
properties ×1
protocols ×1
uiview ×1