<commit_before>// Snippets KeyValueObserver.swift
//
// Copyright © 2016, <NAME>, Pioneering Software, United Kingdom
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the “Software”), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS,” WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO
// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
//------------------------------------------------------------------------------

import Foundation

/// Observes key-value changes. Implements the key-value observing
/// protocol. Responds to key-value change notifications.
///
/// As a side-effect, the observer retains the observed objects. This retention
/// is unidirectional however because the objects do not automatically retain
/// the observer. Unless something retains the observer independently, it will
/// disappear when it goes out of scope. Do not forget to retain your observers
/// for as long as you want them to observe.
public class KeyValueObserver: NSObject {

  /// Retains the observed objects and observed key-paths. Used by the
  /// destructor to cleanly remove the observer from the key-value observation
  /// mechanism. Observer removal does not happen automatically or by default.
  var observing = [(object: NSObject, keyPath: String)]()

  deinit {
    for (object, keyPath) in observing {
      object.removeObserver(self, forKeyPath: keyPath)
    }
  }

  /// - returns: all the objects currently under observation.<commit_msg>Comment about KVO retain cycles<commit_after>// Snippets KeyValueObserver.swift
//
// Copyright © 2016, <NAME>, Pioneering Software, United Kingdom
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the “Software”), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS,” WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO
// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
//------------------------------------------------------------------------------

import Foundation

/// Observes key-value changes. Implements the key-value observing
/// protocol. Responds to key-value change notifications.
///
/// As a side-effect, the observer retains the observed objects. This retention
/// is unidirectional however because the objects do not automatically retain
/// the observer. Unless something retains the observer independently, it will
/// disappear when it goes out of scope. Do not forget to retain your observers
/// for as long as you want them to observe.
public class KeyValueObserver: NSObject {

  /// Retains the observed objects and observed key-paths. Used by the
  /// destructor to cleanly remove the observer from the key-value observation
  /// mechanism. Observer removal does not happen automatically or by default.
  ///
  /// Take care not to create retain cycles between the observer and the
  /// observed. The observer strongly retains the observed, so the observed
  /// should never do likewise to the observer. Otherwise, both will leak.
  var observing = [(object: NSObject, keyPath: String)]()

  deinit {
    for (object, keyPath) in observing {
      object.removeObserver(self, forKeyPath: keyPath)
    }
  }

  /// - returns: all the objects currently under observation.
{'fraction_non_alphanumeric': 0.10527391659852821, 'fraction_numerical': 0.001635322976287817, 'mean_word_length': 3.136094674556213, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2622697', 'n_tokens_mistral': 1178, 'n_tokens_neox': 1094, 'n_words': 634}