Re: Core Data design question: receiving KVO notifications of partially mutated objects

2009-11-03 Thread Sean McBride
On 11/2/09 12:58 PM, Ben Trumbull said:

>This doesn't really have anything to do with Core Data.  However, for
>NSManagedObject, Core Data already provides the change coalescing and
>NSNotifications for you.  You can respond within
>NSManagedObjectContextObjectsDidChangeNotification instead.

So I read the various archive posts about that notification and played
with it a little.  I can see it being handy, especially for added and
removed objects.  The big shortcoming, in my situation anyway, is that
it does not seem to provide me with the keys that changed (in the
NSUpdatedObjectsKey case).  Unless I'm missing something?

Thanks,

--

Sean McBride, B. Eng s...@rogue-research.com
Rogue Researchwww.rogue-research.com
Mac Software Developer  Montréal, Québec, Canada


___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Core Data design question: receiving KVO notifications of partially mutated objects

2009-11-02 Thread Ben Trumbull
>> If your issue is that drawing or recalculation is occurring too
>> frequently after KVO changes, you can consider coalescing and deferring
>> the observers' actions instead of performing them synchronously.  This
>> can be valuable even for less complex KVO issues.
>> 
>> You could also refactor the 3 properties into 1 object.
> 
> Alas, that would require 1) persistent store migration (painful on 10.5)
> and 2) I find it very handy to be able to bind 'colour' to a colourwell
> and 'width' and 'height' to text fields.  Perhaps I have bent my model
> too much in favour of my UI also. :)  But anyway, this 'Rectangle'
> object was just an example.  My real app is a bit harder to explain.
> 
>> Or use an
>> NSNotification instead of KVO to adjust the granularity of notifications
>> to better suit your drawing code.
>> 
>> This doesn't really have anything to do with Core Data.  However, for
>> NSManagedObject, Core Data already provides the change coalescing and
>> NSNotifications for you.  You can respond within
>> NSManagedObjectContextObjectsDidChangeNotification instead.
> 
> Perhaps NSManagedObjectContextObjectsDidChangeNotification is the thing
> I have overlooked!  I currently use it almost nowhere but have tonnes
> and tonnes of KVO observing going on.
> 
> I'll have to RTFM on NSManagedObjectC
> ontextObjectsDidChangeNotification.  Questions that pop to mind though:
> is it safe for me to fetch? to create/delete/mutate ManagedObjects?

I'd recommend performing a selector after delay 0.  You can inspect the objects 
and decide what you want to do with them.  The notification is posted from 
within the change tracking code, so making changes could possibly result in 
them getting caught in between 1 user event and the next.

- Ben

___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Core Data design question: receiving KVO notifications of partially mutated objects

2009-11-02 Thread Sean McBride
On 11/2/09 12:58 PM, Ben Trumbull said:

>> What is considered best practice when it comes to mutating many
>> properties of a managed object, specifically with regard to KVO
>> observers getting notified before all mutations are finished?
>
>This is a problem intrinsic to the design of KVO.  KVO is all about fine
>grained per property notifications.  It's very well suited to that.
>However, it's common for complex objects to be in an intermediate state
>during a KVO notification.
>
>There's no better notion of cross-property coherence than refactoring
>into a different property object that encapsulates everything.
>
>> Let's say I have an Rectangle object.  It has properties: colour, width,
>> height.  Imagine some controller observing all these properties, perhaps
>> to trigger a redraw.
>>
>> If I do:
>>
>> [rect setColour:...];
>> [rect setWidth:...];
>> [rect setHeight:...];
>
>In this example, the best KVO can do is work with a "colored rectangle"
>object that in turn is the 1 property you work with here.  So, this
>would be an example of a granularity of notification that works better
>with NSNotificationCenter
>
>> This is short and readable.  But observers will be notified after each
>> setter.
>
>yup
>
>> This could be a problem if intermediate states are not self-
>> consistent and could also lead to unnecessary redrawing.
>
>And many other performance issues if observers recalculate things too
>aggressively.
>
>> In the general case, I might not even know who is observing.
>
>Well, that's the point of the notification pattern.
>
>>
>> I guess it's safer to create a setColour:width:height: method in my
>> NSManagedObject subclass that does:
>>
>>  [self willAccessValueForKey:@"colour"];
>>  [self willAccessValueForKey:@"width"];
>>
>>  [self setPrimitiveColour:...];
>>  [self setPrimitiveWidth:...];
>>
>>  [self didAccessValueForKey:@"width"];
>>  [self didAccessValueForKey:@"colour"];
>>
>> Is this what I should be doing?
>
>Generally, no.  (setting aside, the calls should be to
>willChangeValueForKey:, btw)

Ben,

Thanks for all the above comments, they have each connected a few dots
in my mind.

>If your issue is that drawing or recalculation is occurring too
>frequently after KVO changes, you can consider coalescing and deferring
>the observers' actions instead of performing them synchronously.  This
>can be valuable even for less complex KVO issues.
>
>You could also refactor the 3 properties into 1 object.

Alas, that would require 1) persistent store migration (painful on 10.5)
and 2) I find it very handy to be able to bind 'colour' to a colourwell
and 'width' and 'height' to text fields.  Perhaps I have bent my model
too much in favour of my UI also. :)  But anyway, this 'Rectangle'
object was just an example.  My real app is a bit harder to explain.

>Or use an
>NSNotification instead of KVO to adjust the granularity of notifications
>to better suit your drawing code.
>
>This doesn't really have anything to do with Core Data.  However, for
>NSManagedObject, Core Data already provides the change coalescing and
>NSNotifications for you.  You can respond within
>NSManagedObjectContextObjectsDidChangeNotification instead.

Perhaps NSManagedObjectContextObjectsDidChangeNotification is the thing
I have overlooked!  I currently use it almost nowhere but have tonnes
and tonnes of KVO observing going on.

I'll have to RTFM on NSManagedObjectC
ontextObjectsDidChangeNotification.  Questions that pop to mind though:
is it safe for me to fetch? to create/delete/mutate ManagedObjects?

Ultimately, my recent problem with 'dangling reference to an invalid
object' made me realise I probably have some design problems, which I
can't quite put my finger on.  I'm pretty sure I'm misusing/abusing KVO
however.

Thanks,

--

Sean McBride, B. Eng s...@rogue-research.com
Rogue Researchwww.rogue-research.com
Mac Software Developer  Montréal, Québec, Canada


___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Core Data design question: receiving KVO notifications of partially mutated objects

2009-11-02 Thread Sean McBride
Graham,

Thanks for the detailed reply!

>I'd say you're going down the wrong path there.

Agreed, hence my post. :)

>Set each property individually. Yes, it will trigger a notification
>for each one - doesn't or shouldn't matter, and unless you can show it
>causes a performance problem, shouldn't be a cause for worry on that
>score. It won't cause multiple redrawing, because even if each one
>posted a -setNeedsDisplayInRect:, the actual drawing will not get
>processed until the next update cycle and invalidating the same area
>three times still only results in one redraw, by which time all the
>properties will be set. Drawing performance is not an issue here
>(unless you are bypassing the update mechanism and forcing the drawing
>on a notification, but that's a different wrong, so you're not doing
>that, are you?).

My 'Rectangle' object with colour, width, and height attributes was an
example of course.  I should probably have clarified that or just not
have used drawing as an example.  You are right about the whole redraw
mechanism of course, and my drawing is in fact fine, and I'm not doing
anything mischievous there.

>The question of whether the separate notifications lead to an invalid
>intermediate state is a more reasonable problem to consider, but it
>normally shouldn't matter either. Normally KVO will be used to update
>your UI and/or maintain undo. You mention Core Data so that will
>handle undo for you but even if you were doing that yourself it
>shouldn't matter. Undo will record each property change and group
>them, so you end up with one undo that undoes all three property
>changes. Any UI that represents each property will also update all at
>once (or appear to) because the drawing update cycle won't actually
>show changes until the update runs and flushes the changes to the
>backing store.

In general, I've found things do indeed work that way, and they work well.

>As a general rule you can and should treat each property in isolation.
>Even if some command sets several at once, you should find that it all
>works correctly unless you've gone out of your way to depend on some
>property state always being paired with some other property state, in
>which case you should probably make that state pair a separate
>property. I think as a general rule the approach you're proposing is
>unnecessary and untidy.

I'm starting to think perhaps the root of my problem is that I am using
KVO in my controller layer to do things that should be done in my model layer.

Sometimes the creation of one ManagedObject, say type 'Foo', requires that:
 - several other ManagedObjects be created and related.
 - several existing ManagedObjects be found and related.

Where is the right place to do such a thing?  Currently, I often do it
by KVO observing, in my NSDocument, the creation of new Foos.  When I
detect new ones, I'll perform some fetches, create new objects, relate
them appropriately, etc.

(In the past, I tried doing such things inside Foo's awakeFromInsert but
I discovered that performing a fetch from that function leads to various
problems.)

Thanks,

--

Sean McBride, B. Eng s...@rogue-research.com
Rogue Researchwww.rogue-research.com
Mac Software Developer  Montréal, Québec, Canada


___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


re: Core Data design question: receiving KVO notifications of partially mutated objects

2009-11-02 Thread Ben Trumbull
> What is considered best practice when it comes to mutating many
> properties of a managed object, specifically with regard to KVO
> observers getting notified before all mutations are finished?

This is a problem intrinsic to the design of KVO.  KVO is all about fine 
grained per property notifications.  It's very well suited to that.  However, 
it's common for complex objects to be in an intermediate state during a KVO 
notification.

There's no better notion of cross-property coherence than refactoring into a 
different property object that encapsulates everything.

> Let's say I have an Rectangle object.  It has properties: colour, width,
> height.  Imagine some controller observing all these properties, perhaps
> to trigger a redraw.
> 
> If I do:
> 
> [rect setColour:...];
> [rect setWidth:...];
> [rect setHeight:...];

In this example, the best KVO can do is work with a "colored rectangle" object 
that in turn is the 1 property you work with here.  So, this would be an 
example of a granularity of notification that works better with 
NSNotificationCenter

> This is short and readable.  But observers will be notified after each
> setter.  

yup

> This could be a problem if intermediate states are not self-
> consistent and could also lead to unnecessary redrawing.  

And many other performance issues if observers recalculate things too 
aggressively.

> In the general case, I might not even know who is observing.

Well, that's the point of the notification pattern.

> 
> I guess it's safer to create a setColour:width:height: method in my
> NSManagedObject subclass that does:
> 
>   [self willAccessValueForKey:@"colour"];
>   [self willAccessValueForKey:@"width"];
> 
>   [self setPrimitiveColour:...];
>   [self setPrimitiveWidth:...];
> 
>   [self didAccessValueForKey:@"width"];
>   [self didAccessValueForKey:@"colour"];
> 
> Is this what I should be doing?

Generally, no.  (setting aside, the calls should be to willChangeValueForKey:, 
btw)

If your issue is that drawing or recalculation is occurring too frequently 
after KVO changes, you can consider coalescing and deferring the observers' 
actions instead of performing them synchronously.  This can be valuable even 
for less complex KVO issues.

You could also refactor the 3 properties into 1 object.  Or use an 
NSNotification instead of KVO to adjust the granularity of notifications to 
better suit your drawing code.

This doesn't really have anything to do with Core Data.  However, for 
NSManagedObject, Core Data already provides the change coalescing and 
NSNotifications for you.  You can respond within 
NSManagedObjectContextObjectsDidChangeNotification instead.

- Ben

___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Core Data design question: receiving KVO notifications of partially mutated objects

2009-10-30 Thread Graham Cox

Hi Sean,

I'd say you're going down the wrong path there.

Set each property individually. Yes, it will trigger a notification  
for each one - doesn't or shouldn't matter, and unless you can show it  
causes a performance problem, shouldn't be a cause for worry on that  
score. It won't cause multiple redrawing, because even if each one  
posted a -setNeedsDisplayInRect:, the actual drawing will not get  
processed until the next update cycle and invalidating the same area  
three times still only results in one redraw, by which time all the  
properties will be set. Drawing performance is not an issue here  
(unless you are bypassing the update mechanism and forcing the drawing  
on a notification, but that's a different wrong, so you're not doing  
that, are you?).


The question of whether the separate notifications lead to an invalid  
intermediate state is a more reasonable problem to consider, but it  
normally shouldn't matter either. Normally KVO will be used to update  
your UI and/or maintain undo. You mention Core Data so that will  
handle undo for you but even if you were doing that yourself it  
shouldn't matter. Undo will record each property change and group  
them, so you end up with one undo that undoes all three property  
changes. Any UI that represents each property will also update all at  
once (or appear to) because the drawing update cycle won't actually  
show changes until the update runs and flushes the changes to the  
backing store.


As a general rule you can and should treat each property in isolation.  
Even if some command sets several at once, you should find that it all  
works correctly unless you've gone out of your way to depend on some  
property state always being paired with some other property state, in  
which case you should probably make that state pair a separate  
property. I think as a general rule the approach you're proposing is  
unnecessary and untidy.


--Graham





On 31/10/2009, at 9:01 AM, Sean McBride wrote:

Let's say I have an Rectangle object.  It has properties: colour,  
width,
height.  Imagine some controller observing all these properties,  
perhaps

to trigger a redraw.

If I do:

[rect setColour:...];
[rect setWidth:...];
[rect setHeight:...];

This is short and readable.  But observers will be notified after each
setter.  This could be a problem if intermediate states are not self-
consistent and could also lead to unnecessary redrawing.  In the  
general

case, I might not even know who is observing.

I guess it's safer to create a setColour:width:height: method in my
NSManagedObject subclass that does:

[self willAccessValueForKey:@"colour"];
[self willAccessValueForKey:@"width"];

[self setPrimitiveColour:...];
[self setPrimitiveWidth:...];

[self didAccessValueForKey:@"width"];
[self didAccessValueForKey:@"colour"];

Is this what I should be doing?

I can see it getting ugly with more than 3 or so properties...


___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Core Data design question: receiving KVO notifications of partially mutated objects

2009-10-30 Thread Kiel Gillard

On 31/10/2009, at 9:01 AM, Sean McBride wrote:


Hi all,

What is considered best practice when it comes to mutating many
properties of a managed object, specifically with regard to KVO
observers getting notified before all mutations are finished?


In situations like these I personally tend to avoid KVO. It's too  
noisy and in some cases incurs too much of a performance overhead.  
But, I have a solution which I describe below.


Let's say I have an Rectangle object.  It has properties: colour,  
width,
height.  Imagine some controller observing all these properties,  
perhaps

to trigger a redraw.

If I do:

[rect setColour:...];
[rect setWidth:...];
[rect setHeight:...];



This is short and readable.  But observers will be notified after each
setter.  This could be a problem if intermediate states are not self-
consistent and could also lead to unnecessary redrawing.  In the  
general

case, I might not even know who is observing.

I guess it's safer to create a setColour:width:height: method in my
NSManagedObject subclass that does:

[self willAccessValueForKey:@"colour"];
[self willAccessValueForKey:@"width"];

[self setPrimitiveColour:...];
[self setPrimitiveWidth:...];

[self didAccessValueForKey:@"width"];
[self didAccessValueForKey:@"colour"];

Is this what I should be doing?

I can see it getting ugly with more than 3 or so properties...


Perhaps make a property that represents the state of the value these  
dependent properties contribute to? For example, is it possible to  
have a "requires redraw" property of the Rectangle? You could simply  
change the value of that property (in the overridden setColor:,  
setWidth:, setLength: methods *sigh*) to indicate the Rectangle object  
requires a redraw? Then, when a third party wants the value of the  
dependent property, you can recalculate it. In the given example, the  
rectangle will only re-draw when it's needed.


Just a few ideas, not sure if they're of any help. They're not coming  
from a Core Data perspective either, just a general one - but I  
wouldn't expect it to be much different?


Kiel

___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Core Data design question: receiving KVO notifications of partially mutated objects

2009-10-30 Thread Sean McBride
Hi all,

What is considered best practice when it comes to mutating many
properties of a managed object, specifically with regard to KVO
observers getting notified before all mutations are finished?

Let's say I have an Rectangle object.  It has properties: colour, width,
height.  Imagine some controller observing all these properties, perhaps
to trigger a redraw.

If I do:

 [rect setColour:...];
 [rect setWidth:...];
 [rect setHeight:...];

This is short and readable.  But observers will be notified after each
setter.  This could be a problem if intermediate states are not self-
consistent and could also lead to unnecessary redrawing.  In the general
case, I might not even know who is observing.

I guess it's safer to create a setColour:width:height: method in my
NSManagedObject subclass that does:

[self willAccessValueForKey:@"colour"];
[self willAccessValueForKey:@"width"];

[self setPrimitiveColour:...];
[self setPrimitiveWidth:...];

[self didAccessValueForKey:@"width"];
[self didAccessValueForKey:@"colour"];

Is this what I should be doing?

I can see it getting ugly with more than 3 or so properties...

Thanks,

--

Sean McBride, B. Eng s...@rogue-research.com
Rogue Researchwww.rogue-research.com
Mac Software Developer  Montréal, Québec, Canada


___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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