I assume you’re referring to the line:
This use of “dynamic” isn’t the same thing as Objective-C’s
@dynamic or Swift’s
dynamic. The docs just mean “properties that change” in this context, and they’re telling you that the AVPlayer is generally very KVO-compliant and intended to be observed that way. “KVO compliant” means it follows the change notification rules. There are many ways to achieve that, both automatic and manual. The docs are just promising that AVPlayer does.
(An important point about Cocoa that distinguishes it from many other systems is that Cocoa handles many things “by convention”. There’s no way to say in code “this is KVO compliant” and there is no way for the compiler to enforce it, but Cocoa developers tend to be very good about following the rules. When ARC was developed, it relied heavily on the fact that Cocoa developers had for years named methods following very specific rules that indicate how memory management is handled. It just added complier enforcement of the rules Cocoa developers had always followed by hand. This is why Cocoa developers get very noisy about naming conventions and capitalization. There are major parts of Cocoa that rely entirely on following consistent naming rules.)
Remembering that the AVPlayer interface is an Objective-C API that happens to be bridged to Swift, there’s no equivalent of the Swift keyword
dynamic in that case. That’s a keyword that tells Swift that this property may be observed and so its accessors can’t be optimized to static dispatch. That’s not something Objective-C requires (or can do; all ObjC properties are “dynamic” in this sense).
@dynamic is a completely different thing, only weakly related to KVO (though it comes up in a lot of KVO-heavy contexts like Core Data). It just means “even though you can’t find an accessor implementation for this property anywhere, trust me, by the time this runs an implementation will be available.” This relies on the ability of ObjC’s runtime to generate implementations dynamically or dispatch in programmer-controlled ways (this still kind of exists in Swift by manipulating the ObjC runtime, but it isn’t really a “Swift” feature).
As for how KVO works, it’s one of the few true “magic tricks” in Cocoa. For a quick intro, see Key-Value Observing Implementation Details. The short version is:
- When you observe an object, a subclass for that object is dynamically created (yes, a new class is invented at runtime).
- The subclass adds calls to
didChangeValue...around all calls to the superclass’s property accessors.
- The object is “ISA-swizzled” to be that new class.
- Magic! (Ok, not really magic; it’s just code, but it’s quite a trick.)
EDIT: The original question never mentioned that it wasn’t working. The reason it’s not working is because you’re not assigning the returned
NSKeyValueObservation in a property; you’re just throwing it away. I’m surprised there’s not a warning about that; I may open a radar.
When the returned
NSKeyValueObservation deallocates, the observation goes away, so this creates an observation and immediately destroys it. You need to store it in a property until you want the observation to go away.