KVUtils.m
author Jens Alfke <jens@mooseyard.com>
Wed Apr 02 14:45:33 2008 -0700 (2008-04-02)
changeset 2 3d3dcc3116d5
child 3 8fad19466c59
permissions -rw-r--r--
UniqueWindowController finds windows that are miniaturized.
Added some date and more graphics utilities.
jens@0
     1
//
jens@0
     2
//  KVUtils.m
jens@0
     3
//  MYUtilities
jens@0
     4
//
jens@0
     5
//  Created by Jens Alfke on 2/25/08.
jens@0
     6
//  Copyright 2008 Jens Alfke. All rights reserved.
jens@0
     7
//
jens@0
     8
jens@0
     9
#import "KVUtils.h"
jens@0
    10
jens@0
    11
jens@0
    12
@implementation Observance
jens@0
    13
jens@0
    14
- (id) initWithTarget: (id)target 
jens@0
    15
               action: (SEL)action
jens@0
    16
             observed: (id)observed
jens@0
    17
              keyPath: (NSString*)keyPath 
jens@0
    18
              options: (NSKeyValueObservingOptions)options
jens@0
    19
{
jens@0
    20
    self = [super init];
jens@0
    21
    if (self != nil) {
jens@0
    22
        _target = target;
jens@0
    23
        _action = action;
jens@0
    24
        _observed = observed;
jens@0
    25
        _keyPath = [keyPath copy];
jens@0
    26
        _options = options;
jens@0
    27
        
jens@0
    28
        options &= ~(MYKeyValueObservingOptionOnce | MYKeyValueObservingOptionDelayed);
jens@0
    29
        
jens@0
    30
        [_observed addObserver: self forKeyPath: _keyPath options: options context: _action];
jens@0
    31
    }
jens@0
    32
    return self;
jens@0
    33
}
jens@0
    34
jens@0
    35
- (void) dealloc
jens@0
    36
{
jens@0
    37
    [_observed removeObserver: self forKeyPath: _keyPath];
jens@0
    38
    [_keyPath release];
jens@0
    39
    [super dealloc];
jens@0
    40
}
jens@0
    41
jens@0
    42
jens@0
    43
@synthesize observed=_observed, keyPath=_keyPath;
jens@0
    44
jens@0
    45
jens@0
    46
- (void) stopObserving
jens@0
    47
{
jens@0
    48
    [_observed removeObserver: self forKeyPath: _keyPath];
jens@0
    49
    _observed = nil;
jens@0
    50
    _target = nil;
jens@0
    51
    _action = NULL;
jens@0
    52
}
jens@0
    53
jens@0
    54
jens@0
    55
- (void) _callTargetWithChange: (NSDictionary*)change
jens@0
    56
{
jens@0
    57
    @try{
jens@0
    58
        [_target performSelector: _action withObject: _observed withObject: change];
jens@0
    59
    }@catch( NSException *x ) {
jens@0
    60
        Warn(@"Uncaught exception in -[%@<%p> %s] while observing change of key-path %@ in %@<%p>: %@",
jens@0
    61
             _target,_target, _action, _keyPath, _observed,_observed, x);
jens@0
    62
    }
jens@0
    63
}
jens@0
    64
jens@0
    65
jens@0
    66
- (void)observeValueForKeyPath:(NSString *)keyPath 
jens@0
    67
                      ofObject:(id)object 
jens@0
    68
                        change:(NSDictionary *)change 
jens@0
    69
                       context:(void *)context
jens@0
    70
{
jens@0
    71
    if( object == _observed ) {
jens@0
    72
        if( _options & MYKeyValueObservingOptionDelayed )
jens@0
    73
            [self performSelector: @selector(_callTargetWithChange:) withObject: change
jens@0
    74
                       afterDelay: 0.0];
jens@0
    75
        else
jens@0
    76
            [self _callTargetWithChange: change];
jens@0
    77
        if( _options & MYKeyValueObservingOptionOnce )
jens@0
    78
            [self stopObserving];
jens@0
    79
    }
jens@0
    80
}
jens@0
    81
jens@0
    82
jens@0
    83
@end
jens@0
    84
jens@0
    85
jens@0
    86
jens@0
    87
jens@0
    88
@implementation Observer
jens@0
    89
jens@0
    90
jens@0
    91
- (id) init
jens@0
    92
{
jens@0
    93
    return [self initWithTarget: self];
jens@0
    94
}
jens@0
    95
jens@0
    96
jens@0
    97
jens@0
    98
- (id) initWithTarget: (id)target
jens@0
    99
{
jens@0
   100
    Assert(target);
jens@0
   101
    self = [super init];
jens@0
   102
    if (self != nil) {
jens@0
   103
        _target = target;
jens@0
   104
        _observances = [[NSMutableArray alloc] init];
jens@0
   105
    }
jens@0
   106
    return self;
jens@0
   107
}
jens@0
   108
jens@0
   109
jens@0
   110
- (void) dealloc
jens@0
   111
{
jens@0
   112
    [self stopObserving];
jens@0
   113
    [_observances release];
jens@0
   114
    [super dealloc];
jens@0
   115
}
jens@0
   116
jens@0
   117
jens@0
   118
@synthesize target=_target;
jens@0
   119
jens@0
   120
jens@0
   121
- (void) observe: (id)observed 
jens@0
   122
         keyPath: (NSString*)keyPath 
jens@0
   123
         options: (NSKeyValueObservingOptions)options
jens@0
   124
          action: (SEL)action
jens@0
   125
{
jens@0
   126
    Observance *o = [[Observance alloc] initWithTarget: _target
jens@0
   127
                                                action: action
jens@0
   128
                                              observed: observed
jens@0
   129
                                               keyPath: keyPath
jens@0
   130
                                               options: options];
jens@0
   131
    [_observances addObject: o];
jens@0
   132
    [o release];
jens@0
   133
}
jens@0
   134
jens@0
   135
jens@0
   136
- (void) observe: (id)observed 
jens@0
   137
         keyPath: (NSString*)keyPath 
jens@0
   138
          action: (SEL)action
jens@0
   139
{
jens@0
   140
    [self observe: observed keyPath: keyPath options: 0 action: action];
jens@0
   141
}
jens@0
   142
jens@0
   143
jens@0
   144
- (void) stopObserving
jens@0
   145
{
jens@0
   146
    [_observances makeObjectsPerformSelector: @selector(stopObserving)];
jens@0
   147
    [_observances removeAllObjects];
jens@0
   148
}
jens@0
   149
jens@0
   150
jens@0
   151
- (void) stopObserving: (id)observed keyPath: (NSString*)keyPath
jens@0
   152
{
jens@0
   153
    // observed or keyPath may be nil
jens@0
   154
    for( int i=_observances.count-1; i>=0; i-- ) {
jens@0
   155
        Observance *o = [_observances objectAtIndex: i];
jens@0
   156
        if( (observed==nil || observed==o.observed) && (keyPath==nil || [keyPath isEqual: o.keyPath]) ) {
jens@0
   157
            [o stopObserving];
jens@0
   158
            [_observances removeObjectAtIndex: i];
jens@0
   159
        }
jens@0
   160
    }
jens@0
   161
}
jens@0
   162
jens@0
   163
@end