Check out http://newwavedigitalmedia.com/blog/?p=132

I'll fix the image issues shortly. But basically it shows how to setup KVO for 
calculated values.  So you could create KVO for each state using 
keyPathsForValuesAffecting<yourKey> then implement getters and setters. So each 
state could be handled via KVO.

Something like

-(NSSet*) keyPathsForValuesAffectingStateZero {
        return [NSSet setWithObject:@"self.value"];
}

So anytime your value changes you will cause a KVO update.

-(BOOL) stateZero {

// check your state.
}

-(void) setStateZero {
        // set your state in for your self.value (which triggers KVO for 
updating the UI.
}

Then you just setup your binding to use stateZero.


On Aug 21, 2012, at 3:53 AM, Andreas Grosam <agro...@onlinehome.de> wrote:

> I'm struggling implementing proper KVO for a number of Bool properties whose 
> state is retrieved from a bit field or a bit mask. These bits are part of a 
> single "_state" integer ivar, which will be modified with atomic operations:
> 
> enum StateT {
>    StateZero  = 0,
>    State_X = 1 << 0,
>    State_1 =  1 << 1,
>    State_2 = 1 << 2,
> 
>    StateBarMask = State_1 | State_2
> };
> 
> 
> @property (BOOL) isFoo;  // shall be KVO compliant
> @property (BOOL) isBar;  // shall be KVO compliant
> 
> 
> - (BOOL) isFoo {
>    return (_state & State_X) != 0;
> }
> 
> - (BOOL) isBar {
>    return (_state & StateBarMask) != 0;
> }
> 
> 
> - (void) doFoo {
>    StateT old_state = OSAtomicOr32OrigBarrier(State_X, &_state);
>    if ( (old_state & State_X) != 0 ) {
>        return; // already in State_X
>    }
>    ...
> }
> 
> 
> - (void) doSomething1 {
>    if (!OSAtomicCompareAndSwap32Barrier(StateZero, State_1, &_state)) {
>        return;
>    }
>    ...
> }
> 
> - (void) doSomething2 {
>    if (!OSAtomicCompareAndSwap32Barrier(State_1, State_2, &_state)) {
>        return;
>    }
>    ...
> }
> 
> 
> 
> So, in order to implement KVO, I would need to track changes of the ivar 
> _state, and invoke 
> -willChangeValueForKey:, and 
> -didChangeValueForKey: 
> appropriately.
> 
> But, how exactly can I accomplish this with the given code above?
> 
> 
> Well, despite the documentation says nothing about the prerequisites when 
> invoking -willChangeValueForKey: -- but I guess, I should invoke this method 
> **before** the actual value changes. And likewise, I should invoke 
> -didChangeValueForKey: **after** the value has been changed.
> 
> With that code above, this seems difficult, though.
> 
> One approach I came up with (which I don't like though) is to use a "shadow 
> variable" for the state, where basically the KVO is implemented on, e.g.:
> 
> - (BOOL) isBar {
>    return (_state_shadow & StateBarMask) != 0;
> }
> 
> 
> When tracking the before and after value of the atomic _state variable, I 
> could then do something like:
> 
> - (void) doSomething1 {
>    if (!OSAtomicCompareAndSwap32Barrier(State_1, State_2, &_state)) {
>        return;
>    }
>    [self modifiedState:State_1 newState:State_2];
>    ...
> }
> 
> In modifiedState:newState: I would invoke the KVO methods and set the 
> _state_shadow accordingly.
> 
> 
> 
> Are there better ways?
> 
> Thanks for hints!
> 
> 
> Andreas
> 
> 
> 
> 
> _______________________________________________
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/scottandrew%40roadrunner.com
> 
> This email sent to scottand...@roadrunner.com


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to