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/archive%40mail-archive.com

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

Reply via email to