Bindings: is there a better way to observe when an object changes?

  • Hi,

    I've created an NSView subclass which needs to be redrawn every time
    an entity object changes, where "changes" means that any of its
    attributes change.

    I've added an "hasChanged" attribute to the entity and made it
    dependent on all the other keys, using -
    setKeys:triggerChangeNotificationsForDependentKey:

    Then I've bound the view instance to the entity object using the
    "hasChanged" key path.

    I don't like this solution very much, though (for instance, I need to
    remember to update the hasChanged dependancies if I add/remove an
    attribute). I tried searching all over the documentation/google for a
    better way to solve this problem, but I couldn't find anything useful.

    Does anybody know a better way or should I stick with this
    implementation?

    --
    Simone Tellini
    http://tellini.info
  • On 9/10/07, Simone Tellini <cocoa-dev...> wrote:
    > Hi,
    >
    > I've created an NSView subclass which needs to be redrawn every time
    > an entity object changes, where "changes" means that any of its
    > attributes change.
    >
    > Does anybody know a better way or should I stick with this
    > implementation?

    Does your view use "any of" the objects attributes? Likely the view is
    only using a subset of items when drawing its representation ("view")
    of the data. So in theory the view knows what is is using and it
    should observe those and only those. ...granted theory and practice
    are often different things.

    If you have a complex interaction between properties of the data you
    can bring sanity again by providing composite properties that hide the
    interactions of these bits of data. In your case you are providing a
    top level one that covers all properties ... however consider
    providing ones better tuned to how your view would look at the data
    (consider adding a category with these to note these are tuned toward
    you view class(es), etc.).

    -Shawn
  • On Sep 10, 2007, at 10:34 AM, Simone Tellini wrote:
    > I've added an "hasChanged" attribute to the entity and made it
    > dependent on all the other keys, using -
    > setKeys:triggerChangeNotificationsForDependentKey:
    > Then I've bound the view instance to the entity object using the
    > "hasChanged" key path.
    > I don't like this solution very much, though (for instance, I need
    > to remember to update the hasChanged dependancies if I add/remove an
    > attribute). I tried searching all over the documentation/google for
    > a better way to solve this problem, but I couldn't find anything
    > useful.
    >
    Well, ultimately you'll have to propagate changes, so you'll have to
    remember to update dependencies somewhere... Keeping them encapsulated
    by a single property means that you only have to remember to update
    them in one place (rather than, for example, updating the view code
    each time you update the entity).  This is in essence the strategy
    illustrated in GraphicsBindings (<http://homepage.mac.com/mmalc/CocoaExamples/GraphicsBindings.zip>) although it also makes explicit:

    + (NSSet *)keysForValuesAffectingDrawingBounds;
    + (NSSet *)keysForValuesAffectingDrawingContents;

    mmalc
  • --- Simone Tellini <cocoa-dev...> wrote:

    > I've created an NSView subclass which needs to be
    > redrawn every time
    > an entity object changes, where "changes" means that
    > any of its
    > attributes change.
    >
    > I've added an "hasChanged" attribute to the entity
    > and made it
    > dependent on all the other keys, using -
    > setKeys:triggerChangeNotificationsForDependentKey:
    >
    > [SNIP]
    >
    > I don't like this solution very much, though (for
    > instance, I need to
    > remember to update the hasChanged dependancies if I
    > add/remove an attribute).

    This is the normal solution as far as I know. If you
    really want *all* attributes of the entity to trigger
    the notification, you could just get them from
    NSEntityDescription rather than listing them yourself,
    but  you're pretty much doing it the normal way. Out
    of curiosity, other than needing to remember to update
    the list of attributes that are considered "changes,"
    are you finding any other problems with this approach?

    Cheers,
    Chuck


    ____________________________________________________________________________________
    Pinpoint customers who are looking for what you sell.
    http://searchmarketing.yahoo.com/
  • Il giorno 10/set/07, alle ore 19:50, Shawn Erickson ha scritto:

    >> I've created an NSView subclass which needs to be redrawn every time
    >> an entity object changes, where "changes" means that any of its
    >> attributes change.
    >>
    >> Does anybody know a better way or should I stick with this
    >> implementation?
    >
    > Does your view use "any of" the objects attributes? Likely the view is

    the view needs all the attributes to render its content, so I really
    need to observe them all.

    --
    Simone Tellini
    http://tellini.info
  • Il giorno 10/set/07, alle ore 19:55, Charles Steinman ha scritto:

    > --- Simone Tellini <cocoa-dev...> wrote:
    >
    >> I've created an NSView subclass which needs to be
    >> redrawn every time
    >> an entity object changes, where "changes" means that
    >> any of its
    >> attributes change.
    >>
    >> I've added an "hasChanged" attribute to the entity
    >> and made it
    >> dependent on all the other keys, using -
    >> setKeys:triggerChangeNotificationsForDependentKey:
    >>
    >> [SNIP]
    >>
    >> I don't like this solution very much, though (for
    >> instance, I need to
    >> remember to update the hasChanged dependancies if I
    >> add/remove an attribute).
    >
    > This is the normal solution as far as I know. If you
    > really want *all* attributes of the entity to trigger
    > the notification, you could just get them from
    > NSEntityDescription rather than listing them yourself,
    > but  you're pretty much doing it the normal way. Out

    NSEntityDescription is 10.4+, apart from that it could have been what
    I was looking for.

    I tried using -attributeKeys from NSClassDescription, but it always
    returned nil.

    > are you finding any other problems with this approach?

    no, it works fine. I just don't think that it's very elegant ;-)

    Anyway, I think that I'm doing the only possible thing at the moment,
    so I'll stop wasting my time on it.

    Thanks everyone.

    --
    Simone Tellini
    http://tellini.info
  • On Sep 10, 2007, at 11:15 AM, Simone Tellini wrote:

    > NSEntityDescription is 10.4+, apart from that it could have been
    > what I was looking for.
    > I tried using -attributeKeys from NSClassDescription, but it always
    > returned nil.
    >
    Core Data doesn't provide "automatic" support for class descriptions:

    "It is important to note that there are no class descriptions by
    default. To use NSClassDescription objects in your code you have to
    implement them for your model classes. For all concrete subclasses,
    you must provide implementations for all instance methods of
    NSClassDescription. (NSClassDescription provides only the
    implementation for the class methods that maintain the cache of
    registered class descriptions.) Once created, you must register a
    class description with the NSClassDescription method
    registerClassDescription:forClass:."
    <http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes
    /NSClassDescription_Class/Reference/Reference.html
    >

    You could use the entity description -- there are several ways to
    retrieve the relevant information (e.g. [propertiesByName allKeys]),
    but...

    >> are you finding any other problems with this approach?
    > no, it works fine. I just don't think that it's very elegant ;-)
    > Anyway, I think that I'm doing the only possible thing at the
    > moment, so I'll stop wasting my time on it.
    >
    I wouldn't say you're "doing the *only* possible thing at the moment"
    -- per Shawn's and my earlier replies, it may be that you can "future-
    proof" your implementation by defining dependent properties for
    attributes affecting drawing.

    mmalc
  • Il giorno 10/set/07, alle ore 20:24, mmalc crawford ha scritto:

    >>> are you finding any other problems with this approach?
    >> no, it works fine. I just don't think that it's very elegant ;-)
    >> Anyway, I think that I'm doing the only possible thing at the
    >> moment, so I'll stop wasting my time on it.
    >>
    > I wouldn't say you're "doing the *only* possible thing at the
    > moment" -- per Shawn's and my earlier replies, it may be that you
    > can "future-proof" your implementation by defining dependent
    > properties for attributes affecting drawing.

    err... unless I've misunderstood you, what you were suggesting is
    exactly what I'm doing.

    As I said, all of the attributes of the entity affect drawing
    (everyone of them flags a bit of graphic content that needs to be
    rendered) and my "hasChanged" property encapsulates them. The
    dependancies are set in +initialize in the entity object, so the view
    doesn't need to know much about it, except how to render it.

    --
    Simone Tellini
    http://tellini.info
  • --- Simone Tellini <cocoa-dev...> wrote:

    > NSEntityDescription is 10.4+, apart from that it
    > could have been what I was looking for.

    I took it from your use of the term "entity" that you
    were using Core Data, which would tie you to 10.4+
    anyway. Just a case of conflicting terminology?

    Cheers,
    Chuck


    ____________________________________________________________________________________
    Take the Internet to Go: Yahoo!Go puts the Internet in your pocket: mail, news, photos & more.
    http://mobile.yahoo.com/go?refer=1GNXIC
  • Il giorno 10/set/07, alle ore 21:28, Charles Steinman ha scritto:

    > --- Simone Tellini <cocoa-dev...> wrote:
    >
    >> NSEntityDescription is 10.4+, apart from that it
    >> could have been what I was looking for.
    >
    > I took it from your use of the term "entity" that you
    > were using Core Data, which would tie you to 10.4+
    > anyway. Just a case of conflicting terminology?

    yes, I guess so. I usually call "entities" objects that have no other
    purpose than that of holding some data, but I'm not using CoreData in
    this case.

    Some people use the term "view" as a synonym, but it would have been
    even more confusing in this context. :-)

    --
    Simone Tellini
    http://tellini.info
  • On Sep 10, 2007, at 12:02 PM, Simone Tellini wrote:

    >> I wouldn't say you're "doing the *only* possible thing at the
    >> moment" -- per Shawn's and my earlier replies, it may be that you
    >> can "future-proof" your implementation by defining dependent
    >> properties for attributes affecting drawing.
    > err... unless I've misunderstood you, what you were suggesting is
    > exactly what I'm doing.
    > As I said, all of the attributes of the entity affect drawing
    > (everyone of them flags a bit of graphic content that needs to be
    > rendered) and my "hasChanged" property encapsulates them. The
    > dependancies are set in +initialize in the entity object, so the
    > view doesn't need to know much about it, except how to render it.
    >
    Oh, understood.  I was trying to emphasise "defining dependent
    properties for attributes *affecting drawing*" -- 'hasChanged' is
    generic, and although at the moment all your attributes affect drawing
    there's a chance that in the future this may not be the case.
    Disambiguating from the outset may therefore be beneficial...

    mmalc
previous month september 2007 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Go to today