2016-03-08 97 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) 。 –