Implementing Manual KVO For Bitfields Set in Atomic Operations
Implementing Manual KVO For Bitfields Set in Atomic Operations
- Subject: Implementing Manual KVO For Bitfields Set in Atomic Operations
- From: Andreas Grosam <email@hidden>
- Date: Tue, 21 Aug 2012 12:53:01 +0200
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