2016-03-08 91 views
0

下面是代码使用KVO在Swift中观察view.center为ios返回NSPoint?

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) 
} 

,输出是:

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

我不知道为什么NS类将出现在iOS版。如何正确观察view.center/frame/transform使用KVO与swift?

回答

3

由于KVO是Objective-C运行时的一部分,因此更改字典是NSDictionary,而不是本机Swift字典。一个NSDictionary只能容纳Objective-C对象(这就是为什么在Swift中,它变成了[String:AnyObject]而不是[String:Any]),并且CGPoint不是Objective-C对象。所以KVO必须将CGPoint包装在一个对象中。

NSValue是包装非对象的通用Objective-C类,当观察属性的类型不是对象类型时,KVO使用它。 NSValue是一个“类集群”,这意味着它定义了一个接口,并可能有专门的,非公共的子类来实现接口。在这种情况下,您会看到其中一个子类的名称:NSConcreteValue

您可以通过请求其CGPointValue性能得到了NSValueCGPoint值:

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

看到NSPoint当您打印的变化词典是历史的偶然原因。 NSPoint类型早于CGPoint,但现在是OS X上CGPoint的别名(在Foundation/NSGeometry.h中定义),在iOS上根本不存在。但是,打印NSPoint/CGPoint的代码未被更改为使用新名称(可能是为了向后兼容),并且在OS X和iOS上都使用相同的代码。

+0

“CGRectValue”和“CGSizeValue”是否也存在? –

+1

是的,他们这样做。检查[NSValue类参考](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSValue_Class/index.html#//apple_ref/occ/instm/NSValue/CGSizeValue) 。 –