# `GSKeyValueObservation observe:forKeyPath:withObserver:options:context:`

*Type Method*

Creates a new observation proxy that observes the given object, forwarding observation messages to the given observer.

## Declaration

```swift
class func observe(_ object: NSObject?, forKeyPath keyPath: String, withObserver observer: NSObject, options: NSKeyValueObservingOptions = [], context: UnsafeMutableRawPointer?) -> Self?
```

```objc
+ (instancetype) observe:(NSObject *) object forKeyPath:(NSString *) keyPath withObserver:(NSObject *) observer options:(NSKeyValueObservingOptions) options context:(void *) context;
```

```python
observe_forKeyPath_withObserver_options_context_(object: NSObject, keyPath: str, observer: NSObject, options: NSKeyValueObservingOptions, context) -> GSKeyValueObservation
```

## Discussion

The returned observation proxy adds itself as an observer of `object` with the given key path, options, and context. Any observation message is then forwarded to the `observer`, to which the proxy holds a weak reference. Before forwarding the message, the proxy checks whether the `observer` is `nil` and if so, removes itself as an observer from `object`.

The proxy also removes itself as an observer when it is deallocated. This allows for a convenient pattern, where the observation is stored in a private property. Replacing the value if the property stops the current observation, if any, and keeps track of the current observation. When the containing object is deallocated, so is the observation property and the observation is stopped.

```objc
@interface Controller ()
@property (strong) GSKeyValueObservation *someObservation;
@end

@implementation Controller
- (void)thingDidUpdate:(Thing *)newThing {
    _someObservation = [GSKeyValueObservation observe:newThing ...];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    // `_someObservation` forwards messages to this method
}
@end
```

When `object` is `nil` or `NSNull`, this method returns `nil`.

