2016-03-08 5 views
0

Вот кодИспользование KVO для наблюдения view.center в swift для 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 класс появится в прошивке. Как правильно наблюдать view.center/frame/transform с помощью KVO с быстрым?

ответ

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.

Вы можете получить значение CGPoint от NSValue, прося его имущества CGPointValue:

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

Причина вы видите NSPoint при печати словаря изменений является исторической случайностью. Тип NSPoint старше CGPoint, но теперь является псевдонимом для CGPoint на OS X (определен в 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) , –