spring
spring

Reputation: 18487

MVC: passing model pointer to a view?

I have an iOS app working and am trying to clean up some of the code structure and implementation. I'd like to clarify my understanding of MVC and improve my code.

Question: is it legit to pass a model to a UIView so the view can render it based on the states of the model elements?

I outline an example below but realize it may not be clear, too tedious to read, etc. The gist is: if a UIView doesn't change any values in a model, is it ok that it retains a weak reference to the model? (say compared to always asking its delegate to return a temporary pointer to the model).

--thanks for any comments!

Example: imagine a UIView which represents a 10 story BUILDING with 1 WINDOW on each floor. The MODEL for this is an NSArray containing 10 instances of custom WINDOW objs. Each WINDOW obj. has a state (light on or off) and a CGRect representing the position of the WINDOW within the overall building view rect.

The controller for the BUILDING instance defines the size of the building view (it's frame) and all the WINDOW objs, including the CGRects,it's state etc., creating the NSArray MODEL. I then assign this MODEL to the UIView for the BUILDING controller (but retain is as a strong property of the BUILDING controller).

The UIView needs to know about the state of the WINDOW and the CGRect in order to draw the view in drawRect.

I guess I could store the CGRects separately since they are not abstract data but it seemed easier to pack it all into one array of objects.

Upvotes: 4

Views: 995

Answers (2)

Rob Napier
Rob Napier

Reputation: 299355

You're on the right track. But there is no reason for the view to have a "weak" reference to the model. It is appropriate for it to have a strong reference to the piece of the model that it is actually displaying, unless you want the piece of model data to be able to vanish while it's being displayed. That would be unusual.

Say I have this thing called WindowPaneView that displays a WindowPane (just avoiding any confusion with UIWindow here). There is nothing wrong with the controller creating the view and handing it a strong reference to the WindowPane. That is a very good design in many cases.

What would be wrong is for the WindowPaneView to make requests to the Building to get the correct window information. The controller should talk to the Building, divvy up the information, and hand each WindowPaneView its proper Window.

It would also be wrong for the WindowPane to know anything about the WindowPaneView. The model must never, ever, know about the views. Madness quickly descends when that happens. But views may certainly know about the specific piece of the model that they are directly displaying. Just no more.

Upvotes: 4

James Eichele
James Eichele

Reputation: 119144

The best choice will depend on the lifetime of the objects in question.

In the example you describe, your controller object should retain both the model and the view, and then provide the view with a weak reference to the model. Your controller is then responsible for all of the memory management, and can properly dispose of the view before the model is released.

If your controller does not own the model object (which can easily happen in an app with many different co-operating controller objects), then you have two options:

  1. Retain a strong reference to the NSArray
  2. Hold a copy (perhaps a deep-copy) of the NSArray object which the NSView object then use for as long as necessary.

In general, I would lean towards option 2 because it removes the need for any long-term memory management concerns.

Upvotes: 1

Related Questions