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 <[email protected]> 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 ([email protected])
>
> 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 [email protected]
_______________________________________________
Cocoa-dev mailing list ([email protected])
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 [email protected]