标签: key-value-observing

使用KVO更改属性时发送通知

我有一个myName在我班上命名的房产,如:

@property (nonatomic, strong) NSString *myName;
Run Code Online (Sandbox Code Playgroud)

myName属性的值发生变化时,我需要发送通知.

现在我做的事情如下:

- (void)setMyName:(NSString *)name
{
  _myName = name;
  [[NSNotificationCenter defaultCenter] postNotificationName:CHANGE_NOTIFICATION object:nil];
}
Run Code Online (Sandbox Code Playgroud)

我知道在iOS中有类似Key-Value Observing的东西.但我不知道如何实现它,我阅读了整个文档,但无法得到很好的理解.

请帮助我了解如何在不使用自定义setter的情况下实现相同的功能.

properties objective-c key-value-observing ios

15
推荐指数
3
解决办法
1万
查看次数

什么时候使用KVO?

我已经阅读了很多关于KVO的文档,但我仍然对何时使用它感到困惑.

如果objA想监视某个属性objB,如下:

self.objB = [[ObjB alloc] init];
[self.objB addObserver:self
            forKeyPath:@"address"
               options:0
               context:nil];
Run Code Online (Sandbox Code Playgroud)

所以,如果objB属性发生变化,并且只能更改self,为什么不这样做:

self.objB.property = @"newValue";
[self doSomethingBasedOnNewValueOfObjBnewProperty];
Run Code Online (Sandbox Code Playgroud)

代替

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context

{
    if(keyPath == @"address") {
        [self doSomethingBasedOnNewValueOfObjBnewProperty];
    }
}
Run Code Online (Sandbox Code Playgroud)

当与单例一起使用时可能很有用,例如self.objB = [ObjB sharedInstance],其中属性可能被其他对象更改.这是唯一的用例吗?

objective-c key-value-observing

15
推荐指数
2
解决办法
2786
查看次数

如何在UIView与superView分离时收到通知?

似乎UIView没有像" didRemoveFromSuperview"或" willRemoveFromSuperview" 那样的方法.那么,当UIView从superView中删除时,如何监听事件?我应该使用KVO吗?提前致谢!

iphone key-value-observing uiview ios

14
推荐指数
4
解决办法
1万
查看次数

两个类之间的iPhone KVO

我的应用程序类A和类B中有两个类.A类和B类都是UIViewController的实例.A类有一个按钮,推送时将B类推入堆栈.B类有一个A类想要观察的字符串,并根据需要更新它的接口.我已经能够使用: [self addObserver:self forKeyPath:@"name" options:0 context:NULL];在B类中查看对字符串的更改.当我尝试在A类viewWillAppear方法中使用以下内容时:

ClassB *b = [[ClassB alloc]init];
[b addObserver:self forKeyPath:@"name" options:0 context:NULL];
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)

尝试从A中查看B中所做的更新时没有触发任何操作.我觉得这个问题很傻但是KVO如何在iOS中的两个类之间工作?我知道这应该有效.

iphone key-value-observing ios

14
推荐指数
1
解决办法
2万
查看次数

NSProxy和关键价值观察

NSProxy对于那些尚不存在的对象来说,它们看起来效果非常好.例如.

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
    return [self.target methodSignatureForSelector:sel];
}

- (void)forwardInvocation:(NSInvocation *)invocation {
    [invocation invokeWithTarget:self.target];
}
Run Code Online (Sandbox Code Playgroud)

上面的代码将透明地将任何方法调用传递给代理所代表的目标.但是,它似乎没有处理目标上的KVO观察和通知.我试图使用一个NSProxy子类代表要传递给的对象NSTableView,但我收到以下错误.

Cannot update for observer <NSAutounbinderObservance 0x105889dd0> for
 the key path "objectValue.status" from <NSTableCellView 0x105886a80>,
 most likely because the value for the key "objectValue" has changed
 without an appropriate KVO notification being sent. Check the 
KVO-compliance of the NSTableCellView class.
Run Code Online (Sandbox Code Playgroud)

有没有办法让透明NSProxy符合KVO标准?

cocoa objective-c key-value-observing nsproxy

14
推荐指数
1
解决办法
2157
查看次数

NSKeyValueObservation:无法从对象中删除关键路径的观察者,因为它未注册为观察者

我在我的应用程序中遇到随机崩溃(我无法在我拥有的设备上重现),例外情况:

无法从AVPlayerLayer 0xaddress中删除关键路径"readyForDisplay"的观察者Foundation.NSKeyValueObservation 0xaddress,因为它未注册为观察者.

当我释放包含AVPlayerLayer的UIView时会发生这种情况.

我的初学者:

private var playerLayer : AVPlayerLayer { return self.layer as! AVPlayerLayer }

init(withURL url : URL) {
    ...
    self.asset = AVURLAsset(url: url)
    self.playerItem = AVPlayerItem(asset: self.asset)
    self.avPlayer = AVPlayer(playerItem: self.playerItem)
    super.init(frame: .zero)
    ...
    let avPlayerLayerIsReadyForDisplayObs = self.playerLayer.observe(\AVPlayerLayer.isReadyForDisplay, options: [.new]) { [weak self] (plLayer, change) in ... }
    self.kvoPlayerObservers = [..., avPlayerLayerIsReadyForDisplayObs, ...]
    ...
    }
Run Code Online (Sandbox Code Playgroud)

我的deinit抛出异常:

deinit {
    self.kvoPlayerObservers.forEach { $0.invalidate() }
    ...
    NotificationCenter.default.removeObserver(self)
}
Run Code Online (Sandbox Code Playgroud)

根据Crashlytics的说法,它发生在不同iPhone上的iOS 11.4.1上.

导致的代码deinit非常简单:

// Some UIViewController context.
self.viewWithAVLayer?.removeFromSuperview()
self.viewWithAVLayer …
Run Code Online (Sandbox Code Playgroud)

key-value-observing ios avplayerlayer swift

14
推荐指数
1
解决办法
1464
查看次数

来自observeValueForKeyPath:ofObject的参数:change:context:

我想知道这个方法的参数会返回什么.

- (void) observeValueForKeyPath:(NSString *)keyPath
                       ofObject:(id)object
                         change:(NSDictionary *)change
                        context:(void *)context;
Run Code Online (Sandbox Code Playgroud)

文档中

keyPath相对于对象的键路径,已更改的值.

object key path keyPath的源对象.

change一个字典,描述对关键路径keyPath的属性值所做的更改相对于object.

context注册接收器以接收键值观察通知时提供的值.

您能否为我解释这些参数,因为我发现文档有点难以理解.

parameters cocoa objective-c key-value-observing

13
推荐指数
1
解决办法
9739
查看次数

Swift 4(BETA 2)KVO崩溃,基于WWDC谈话

我试图得到一些非常类似于WWV 2017基金会谈论KVO观察的例子.我看到的唯一不同于那次谈话的差异是,我不得不调用super.init(),我不得不隐藏地解开"kvo"令牌.

以下用于游乐场:

struct Node  {
    let title: String
    let leaf: Bool
    var children: [String: Node] = [:]
}

let t = Node(title:"hello", leaf:false, children:[:])
let k1 = \Node.leaf
let k2 = \Node.children
t[keyPath: k1] // returns "false" works
t[keyPath: k2] // returns "[:]" works

@objcMembers class MyController : NSObject {
    dynamic var tr: Node
    var kvo : NSKeyValueObservation!
    init(t: Node) {
        tr = t
        super.init()
        kvo = observe(\.tr) { object, change in
            print("\(object)  \(change)")
        }
    }
}


let x …
Run Code Online (Sandbox Code Playgroud)

key-value-observing swift

13
推荐指数
1
解决办法
5551
查看次数

Swift 4使用KVO收听音量变化

我刚刚更新到Swift 4和Xcode 9并得到(swiftlint)警告,以下代码告诉我现在应该使用KVO:

警告:

(基于块的KVO违规:在使用Swift 3.2或更高版本时,首选基于新块的KVO API和键路径.(block_based_kvo))

旧代码:

override func observeValue(forKeyPath keyPath: String?,
                           of object: Any?,
                           change: [NSKeyValueChangeKey : Any]?,
                           context: UnsafeMutableRawPointer?) {
    if keyPath == "outputVolume"{
        guard let newKey = change?[NSKeyValueChangeKey.newKey] as? NSNumber else {
            fatalError("Could not unwrap optional content of new key")
        }

        let volume = newKey.floatValue

        print("volume " + volume.description)
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试修复:

let audioSession = AVAudioSession.sharedInstance()
    audioSession.observe(\.outputVolume) { (av, change) in
        print("volume \(av.outputVolume)")
}
Run Code Online (Sandbox Code Playgroud)

Apple 在这里声称大多数属性应该是dynamic(我知道这是AVPlayer而不是AVAudioSession).我查了一下,但dynamic在AVPlayer属性中找不到任何声明,并想知道它是如何工作的(如果我没有弄错,那些是KVO工作所必需的).

编辑:

我不确定它是否不会触发,因为它根本不起作用或者是由于我尝试归档的原因.总的来说,我希望通过推动硬件音量摇杆来获得有关音量变化的通知.

key-value-observing ios swiftlint swift4 xcode9

13
推荐指数
2
解决办法
4766
查看次数

当摄像机视图中的内容发生变化时,"点按以对焦"至"自动对焦".像在相机应用程序或iOS的UIImagePickerController中的逻辑?

当视图中的内容发生变化时,如何在失去焦点后自动处理从特定POI的"点击到焦点"切换回"自动对焦"状态?如果您注意到相机应用程序或UIImagePickerController中的焦点行为,在您点击一些区域并移动手机后,相机可以自动切换到屏幕中央的连续自动对焦.

我需要比UIImagePickerController可以提供的更多的灵活性,所以我需要首先使用AVFoundation来模仿UIImagePickerController行为......

camera key-value-observing avfoundation autofocus ios

12
推荐指数
1
解决办法
7541
查看次数