Re: Design Question: Bindings & Custom Views
Re: Design Question: Bindings & Custom Views
- Subject: Re: Design Question: Bindings & Custom Views
- From: "Oleg Krupnov" <email@hidden>
- Date: Thu, 28 Aug 2008 16:01:04 +0300
Thanks, that mostly answers my question, finally. And the short answer
is "No" :). There is no standard Cocoa way of doing this and it's up
to me how to implement it. I just wanted to make sure I was not
reinventing the wheel.
You are correct in suspecting me in a kind of MVC purism (typical for
a newbie :). Indeed, I used to understand the MVC pattern that the
model should be strictly separated from the views and inherently
assume a one-to-many relationship between the model and the views. It
means that the model should not include properties and messages that
are view-specific, because the number and kind of views is a black box
for the model. The model might have a message for creating thumbnails,
but it should not include a thumbnail ivar, because there can be two
views of the same model, each requiring thumbnails of different kind.
By adding ivars and messages that every view in the world might need
will result in what is called "fat interface" for the model. The
encapsulation becomes poor and unnecessary dependancies are
introduced. It may work well at the beginning for it seems simple, but
it may fire back and require refactoring as the program grows more
complex.
Your solution with the static dictionary looks similar to what I had
in mind, except that I intended this dictionary to be owned by the
custom NSView and not be static(I don't need different shapes to share
the same thumbnails, each one is unique). By keying in the model
objects pointers or their unique IDs, I could retrieve view-specific
data from the dictionary. I could even wrap that data together with
the messages for drawing and hit testing, so that I don't even have to
use categories on model objects. Perhaps I will stick to this
solution.
Thanks!
On Thu, Aug 28, 2008 at 3:11 PM, Graham Cox <email@hidden> wrote:
>
> On 28 Aug 2008, at 8:26 pm, Oleg Krupnov wrote:
>
>> In your image browser example, this problem sounds as follows: where
>> to store the cached thumbnail images, to avoid re-creating them anew
>> in each drawRect call? Also, if a thumbnail is in process of dragging
>> inside the custom view, where to save the flag that the thumbnail
>> should be highlighted, the next time we draw it in drawRect?
>>
>> I thought this kind of problem should be well-known and commonplace
>> among Cocoa developers...
>
>
> BTW, for some reason my feed from the list was delayed by several hours and
> only just came "unstuck", so it seems you've had some response on this
> already I didn't know about. In which case my first response probably isn't
> all that useful.
>
> Regarding the above though, if this is similar to your situation - what's
> really wrong with model objects caching a thumbnail? Being a slave to MVC is
> going to lead to suboptimal solutions just as ignoring MVC altogether is
> going to be. The cached thumbnail has to be stored somewhere, right? Where,
> doesn't really matter. So if a model object has a -thumbnail method that
> returns the thumbnail when you need it, what's wrong with that? The
> thumbnail doesn't need to end up permanently stored by the model when
> archived, just created lazily when required. If the model object is the best
> object to make and cache that thumbnail (i.e. it has all the state
> information to hand to do so) why not let it? A view that displays the
> thumbnail can then just request it directly from the object in question
> instead of going round the houses to generate a thumbnail simply to avoid
> the model object getting its hands dirty. Some may feel differently but I
> don't see that this violates MVC in any significant way and it's much
> simpler.
>
> An example from my DrawKit project - a style object is part of the model in
> that it represents a number of combined graphical properties of a drawn
> object. But a UI that deals in styles will often want a small thumbnail or
> icon to preview the style to the user. So my style objects handle that as
> well - they implement an -image method. Internally they also create it
> lazily and cache it for efficiency, but none of that really impacts the
> integrity of the model in any way. If it makes things feel better, you could
> put these methods into a category (I don't in this case). For the cache I
> use a statically declared dictionary within the -image method so that a) I
> don't need ivars in my style objects to store it and b) the static variable
> is independent and invisible to anything other than that specific method.
> (If this is what you were alluding to originally then I may have
> misunderstood - this seems a reasonable approach to me and works a treat).
> What I definitely don't do however is pass a view reference to the model
> object at any point - the -image method returns an image of that model
> object but it makes no assumptions about its use nor tailors its image
> generation according to the type of view. If you need to parameterise what a
> method like this does, do it in the abstract and let the caller/client
> decide what parameters to pass for its needs.
>
> Regarding selection of objects, that isn't part of the model state per se.
> You probably want to avoid having a "is selected" flag in your model object.
> However, it's often useful to let an object decide for itself what graphical
> form a selection highlight should take. So why not simply pass the "is
> selected" flag as a parameter to its draw method? When your view's
> -drawRect: is called, something is going to have to iterate over the objects
> and draw them. At that point you can determine if an object is selected or
> not and pass the flag as appropriate. The easiest way to handle selection
> that I've found is just to maintain a set of the the objects that are
> selected. To select an object, add it to this set. Then when drawing you can
> test for membership of this set and pass the flag to the draw method of the
> object. This is the way I did it in DrawKit and haven't discovered any
> obvious downside to it. It also fits in with bindings since you already have
> a list of "the selection" at your disposal at all times. The "owner" of the
> selection set could be the view but more likely it's part of a controller -
> depends really on whether you conceptually think of the selection as
> pertaining to just one view or to be the same across several. However, by
> passing the "selected" flag to the object when you draw it, you can do it
> either way without tying yourself down.
>
> Any help?
>
> Graham
>
>
>
_______________________________________________
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