Re: Implementing Manual KVO For Bitfields Set in Atomic Operations
Re: Implementing Manual KVO For Bitfields Set in Atomic Operations
- Subject: Re: Implementing Manual KVO For Bitfields Set in Atomic Operations
- From: Scott A Andrew <email@hidden>
- Date: Tue, 21 Aug 2012 11:07:21 -0700
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@hidden> 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@hidden)
>
> 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:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden