0

Here is the code

view.addObserver(self, forKeyPath: "center", options: .New, context: nil)

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
    guard let change = change else {
        return
    }

    print(change)

    guard let newCenter = change["new"] else {
        return
    }

    print(newCenter.dynamicType)
}

And the output is :

["new": NSPoint: {50, 50.5}, "kind": 1]
NSConcreteValue

I don't know why NS class will appear in iOS. How to correctly observe view.center/frame/transform using KVO with swift?

Morty Choi
  • 2,466
  • 1
  • 18
  • 26

1 Answers1

3

Since KVO is part of the Objective-C runtime, the change dictionary is an NSDictionary, not a native Swift dictionary. An NSDictionary can only hold Objective-C objects (which is why, in Swift, it becomes a [String:AnyObject], not a [String:Any]), and CGPoint is not an Objective-C object. So KVO has to wrap the CGPoint in an object.

NSValue is a generic Objective-C class for wrapping non-objects, and KVO uses it when the observed property's type is not an object type. NSValue is a “class cluster”, which means it defines an interface and may have specialized, non-public subclasses that implement the interface. In this case, you're seeing the name of one of those subclasses: NSConcreteValue.

You can get the CGPoint value from the NSValue by asking for its CGPointValue property:

guard let newCenter = change["new"]?.CGPointValue else {
    return
}

The reason you see NSPoint when you print the change dictionary is an accident of history. The NSPoint type is older than CGPoint, but is now an alias for CGPoint on OS X (defined in Foundation/NSGeometry.h), and doesn't exist at all on iOS. However, the code to print NSPoint/CGPoint was not changed to use the new name (probably for backward compatibility) and the same code is used on both OS X and iOS.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Does `CGRectValue` and `CGSizeValue` exits too? – Morty Choi Mar 08 '16 at 03:41
  • 1
    Yes they do. Check the [NSValue Class Reference](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSValue_Class/index.html#//apple_ref/occ/instm/NSValue/CGSizeValue). – rob mayoff Mar 08 '16 at 03:43