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: Wed, 22 Aug 2012 07:48:57 -0700
Why not have an update flags function and a set of booleans that represent the flags.
@interface someInterface {
BOOL _isFoo;
BOOL _isBar;
}
@property (nonatomic, readonly, assign) BOOL isFoo;
@property (nonatomic, readonly, assign) BOOL isBar;
-(void) updateFlags:(int)bits;
@end
Then in your m file.
@interface someInterface()
// these you can set in update flags to trigger KVO
@property (nonatomic, readwrite, assign) BOOL isFoo;
@property (nonatomic, readwrite, assign) BOOL isBar;
@end
@implement someInterface
@synthesize isFoo = _isFoo;
@synthesize isBar = _isBar;
-(void) updateFlags:(int)bits {
BOOL newFoo = (flags & 0x3) != 0;
if ((newFoo) != self.isFoo)
self.isFoo = newFoo;
.......
}
I wouldn't really worry about KVO being fired if value hasn't changed, unless its changing a lot. When ever the int changes you can call into updateFlags to update the BOOLs as needed which then fires off the KVO. You can use a temporary bool to check old against new if you want to selectively cause firing based on what has changed.
Scott
On Aug 22, 2012, at 3:31 AM, Andreas Grosam <email@hidden> wrote:
>
> On 21.08.2012, at 22:35, Quincey Morris wrote:
>
>> This doesn't make sense as it stands. You've declared properties that need setters as well as getters, and the setters (which you didn't show code for) will give you KVO compliance without any explicit will/didChanging.
> Well, the description says it all, I think ;)
>
> I put the "code" in only for illustration. Stupidly, I didn't wrote the property declaration correctly (just typed into mail).
>
> However, I think the text clearly states that I want to *retrieve* a *bool* value from *several* properties where the value for each property will be deduced from a set of bits from a common variable. The snippets show how the *getters* are implemented and how I set the ivar _state. There are no setters.
>
>
> The correct public property declaration should be:
>
> @property (nonatomic, readonly) BOOL isFoo;
> @property (nonatomic, readonly) BOOL isBar;
>
>>
>> The only reason for coding will/didChange explicitly would be if you need to do an end run around the setters -- either because you wish to coalesce notifications for multiple property changes, or because you want to change sets of bits that don't map directly to single properties.
> With respect, there are other reasons, too. For example, you need to implement these methods manually if the property is declared in a super class and if that super class does not support KVO. An example would be property "isExecuting" from NSOperation if you implement a concurrent operation. In fact, I'm trying to implement the *required* manual KVO compliance in a subclass of NSOperation.
>
> Another reason is, if you have a property that derives its value r from a function f(x) for which there is no inverse function f-1 (f, in a mathematical sense). In this case, there is no corresponding setter, since this function f is *not invertible*.
>
> Example:
>
> bool f(int x) {
> return (x & 0x03) != 0;
> }
>
> This function f(x) is not bijective, that is there exists no invertible function. Or, in other words, given an output value r you cannot find a unique corresponding input x.
>
>
> @property (readonly) R foo;
>
> -(R) foo { return f(_x); }
>
> Since, f(x) is not bijective, then there is no:
> -(void) setFoo:(R)r { ?? }
>
>
> So in this case, when _x changes, I need to implement manual KVO.
>
>
> This is exactly the problem I have, and which I described in my first post. The implementation of property getter -bar shows, that its function is not invertible. Thus, there can be no setter like:
> -(void)setBar:(BOOL)
>
> and KVO needs to be implemented manually, when the dependent variable _state changes.
>
>
>> Either way, KVO notifications are never "inside" the atomicity of the properties, which means that the values passed in the notification (old or new value) won't necessarily have any meaning in a multi-threaded environment.
> Yes, and this is not what I strive to accomplish. Especially, I don't try to manage concurrency with KVO! I'm totally aware that when retrieving a state, it can already be stale.
>
>> It might be fine just to call both willChange and didChange after the bits are actually changed.
> OK, that's what my question was all about. If I do this, I especially don't want to receive change notifications when the state did not actually change, and furthermore, that the change dictionary in the notification method is correctly setup.
>
>>
>> I have to mention, though, that it looks a bit like you're implementing atomicity where you really need thread safety. But that may be just because of details you've left out of your example code.
>
> Atomic access is one approach which *may* ensure thread-safety, but it may not always effectual. In my case it is sufficient to access shared resources via atomic operations (it's just the _state ivar).
>
> The other reason using atomic operations is to prevent a method to be executed when the prerequisite of the current state is not given. Taken together, this makes the system thread safe.
>
>
> Hopefully, I could express my problem more clearly.
>
> Many Thanks for your input!
>
>
> Regards
> 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