2016-11-03 7 views
1

Я использую стороннюю библиотеку, для которой у меня есть заголовочный файл ObjC. В этом файле заголовка есть свойство, которое я хотел бы наблюдать из моего кода Swift. Теперь мой вопрос: могу ли я каким-то образом расширить класс ObjC, не имея файла .m, чтобы я мог наблюдать свойство, когда оно изменяется в Swift? Я думал об использовании KVO, но тогда мне нужно было бы изменить реализацию класса ObjC?Обратите внимание, что объект принадлежит классу ObjC в Swift

Спасибо за вашу помощь

ответ

0

Если предположить, что ваш класс Objective-C является key-value observing compliant, вы можете использовать addObserver(_:forKeyPath:options:context:). Вот пример:

// Person.h 
#import <Foundation/Foundation.h> 

@interface Person : NSObject 

@property NSString * name; 
@property int age; 

- (id) initWithName:(NSString *) name 
       age:(int) age; 

@end 

// Person.m 
#import "Person.h" 

@implementation Person 

- (id) initWithName:(NSString *) name 
       age:(int) age 
{ 
    if (self = [super init]) { 
     self.name = name; 
     self.age = age; 
    } 

    return self; 
} 

@end 

и снова в Swift:

extension Person { 
    override public func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { 
     if let keyPath = keyPath, 
      let change = change, 
      let oldValue = change[NSKeyValueChangeOldKey], 
      let newValue = change[NSKeyValueChangeNewKey] { 

      print("'\(keyPath)' has changed from \(oldValue) to \(newValue)") 
     } 
    } 
} 

let p = Person(name: "John", age: 42) 

// Start observing changes 
// In this case, the object will observe itself 
p.addObserver(p, forKeyPath: "name", options: [.New, .Old], context: nil) 
p.addObserver(p, forKeyPath: "age", options: [.New, .Old], context: nil) 

p.name = "Jack" 
p.age = 50 

// You must remove all observers before releasing the object 
p.removeObserver(p, forKeyPath: "name") 
p.removeObserver(p, forKeyPath: "age")