10

Is it possible to add observers to simple variables such as BOOLs or NSIntegers and see when they change?

Thanks!

Alex
  • 7,432
  • 20
  • 75
  • 118

4 Answers4

22

You observe keys to be notified when their value changes. The data type can be anything. For anything defined as an Objective-C property (with @property in the .h file) this is ready to go so if you want to observe a BOOL property you add to a view controller you do it as follows:

in myViewController.h:

@interface myViewController : UIViewController {
    BOOL      mySetting;
}

@property (nonatomic)    BOOL    mySetting;

in myViewController.m

@implementation myViewController

@synthesize mySetting;

// rest of myViewController implementation

@end

in otherViewController.m:

// assumes myVC is a defined property of otherViewController

- (void)presentMyViewController {
    self.myVC = [[[MyViewController alloc] init] autorelease];
    // note: remove self as an observer before myVC is released/dealloced
    [self.myVC addObserver:self forKeyPath:@"mySetting" options:0 context:nil];
    // present myVC modally or with navigation controller here
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (object == self.myVC && [keyPath isEqualToString:@"mySetting"]) {
        NSLog(@"OtherVC: The value of self.myVC.mySetting has changed");
    }
}
XJones
  • 21,959
  • 10
  • 67
  • 82
5

I believe what you meant was: How to get INT or BOOL value from the 'change' dictionary if the property has changed.

You can simply do it this way:

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if ([keyPath isEqualToString:@"mySetting"])
    {
        NSNumber *mySettingNum = [change objectForKey:NSKeyValueChangeNewKey];
        BOOL newSetting = [mySettingNum boolValue];
        NSLog(@"mySetting is %s", (newSetting ? "true" : "false")); 
        return;
    }

    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
Kuba S.
  • 186
  • 2
  • 4
  • Is there a specific reason why you would return if you handled your variable and not call the super method? This way the super method is only called when KVO is called and it's not your variable. – Leon Feb 23 '17 at 10:02
1

Yes; the only requirement is that the object in which those variables occur are key-value compliant for those properties.

Daniel Dickison
  • 21,832
  • 13
  • 69
  • 89
-2

If they are properties of objects then yes.

If they are not properties then no.

deanWombourne
  • 38,189
  • 13
  • 98
  • 110
  • Nothing, I just don't know how to use it to look for a change in the variable's value. – Alex Apr 11 '11 at 16:01
  • Correct me if i'm wrong, but afaik it doesn't have to be a property, it can be 2 methods a getter - [boolName] and a setter - set[boolName] that will take and return an NSNumber – Zaky German Apr 11 '11 at 16:03
  • I'm actually referring to the editing BOOL variables from UIViewControllers. So in a way they are properties, but no of objects I made. – Alex Apr 11 '11 at 16:06
  • Then yes - if they're properties go and observe away (assuming they are key-value compliant but I've just taken it as read that they will be!) - Have you tried to observe them? What happens when you do? – deanWombourne Apr 11 '11 at 16:15
  • Seems to me like I can't add an observer...If I try to say [self.editing addObserver], there will be no automatic completion. – Alex Apr 11 '11 at 16:26
  • 1
    No but you can add an observer to self, passing in edit as the path :) – deanWombourne Apr 11 '11 at 17:14