I'm attempting to do a better job of keeping my data and my visual representation of data separate in a new project and I'm having some trouble with the abstraction.
I have a list of objects in a set that are part of an inventory and I use that data to generate some UIImageViews that get placed into the interface, thus keeping my models and views separate. When a user taps on the UIImageView, I want to be able to take an action on the data in the set as well as modifying the corresponding view.
How do I keep track of the object that is being represented by the UIImageView? I would think there's some sort of mechanism by which I can say "here's a reference to the object that you represent" but I can't figure out if that exists or if there's a more accepted way to achieve the view/model separation.
you could create and object that is an extension of the ImageView and upon initialization of that view, associate a property in the view to your data associated with the view.
Related
I am badly struck in a issue where I am trying to populate the nestableview lazily. Below is my approach.
I have created a custom class PRIList where it has an instance of array to manage the models.
I have bound the priList.items to the array controller in the xib where items is not an instance in PRIList but to support lazy loading I have implemented the methods countOfItems and objectInItemsAtIndex:.
Initialy when I populate the PRIList I populate few objects (say 50) with valid objects and rest with the faulty objects. In the objectInItemsAtIndex I check if the item at particular index is valid or faulty. If it is faulty I fetch next set of 50 objects.
What I understand is NSArrayController calls the method objectInItemsAtIndex for only the visible rows in the table view. But the problem here is as soon as set the PRIList the objectInItemsAtIndex method is called for all the objects. This is even called when some selection is changed in table view (the stack trace shows this method is called from [_NSModelObservingTracker startObservingModelObjectAtReferenceIndex])
Basically I want to fetch the records whenever the user scrolls down in the table view.
I followed the same approach in a different project in Lion. It worked there. Currently I am in Mavericks.
I tried overriding the isCompatibleWithResponsiveScrolling in the custom table view and returned it to NO. Still no luck.
Any help is very much appreciated.
First, have you assigned or bound the sort descriptors of the array controller? Or set any columns to automatically generate sort descriptors? (I'm not sure that latter is relevant. It depends on whether the column is sorted by default.)
In any case, if the array controller feels the need to sort the objects in order to arrange the objects, then it will need to load all of the contents. I was under the impression that it always does so, anyway, although you report that it works.
For an issue like this, I'd recommend that you go for full manual control. That means not using bindings or an array controller. Use a data source.
I have a view controller placeViewController which pulls in a bunch of Place objects, and from these loads and populates a matching bunch of PlaceView objects which are then displayed as subviews to its main view.
I need to update these views periodically which requires information from the model and other places to be pushed into the views
How should I properly structure this?
Keep an array of Place objects and give the model a PlaceView property to store pointers to the views
Keep an array of PlaceView objects and give the view a Place property to store pointers to the places
Keep both arrays and use a lot of indexOfObject objectAtIndex to jump between them
Some other way??
I need to update these views periodically which requires information
from the model and other places to be pushed into the views
You should really focus on an ObserverPattern. Yours views register to "notifications", and when changes are made, your registered views are notified.
http://en.wikipedia.org/wiki/Observer_pattern
You still can use NSNotificationCenter, but it will not futfill your needs since you need yours views make update per Place object (paired like a dictionary). So i recommend you to implement your own.
It will loose coupled because your controller will just only make glue between the observer and your views, and all the "logic" will be handled by the observer.
Well basvk got the answer in his comment but hasn't posted an actual answer for me to mark correct.
So here it is: "I would create a NSMutableArray with PlaceView objects. And the PlaceView class holds a #property Place *place"
I'm starting a small project that displays circles having random radii, random color and random position on the screen. I want to implement this using the MVC paradigm in Objective C.
I have a class Circle that contains the following instance variables:
CGFloat radius
CGPoint center
UIColor radiusColor
This class doesn't contain methods, it just holds data. It is put in a separate file. (Circle.m & Circle.h)
I have a myModel class that is supposed to be the model for my MVC. It contains methods that randomly generate centers inside bound of my view, where the bound dimensions are requested from the View throughout the controller.
Every time a random property (that is center, color and radius) is generated, an instance of the Circle class is created within the myModel class, and stored in an NSMutableArray.
When the generation is done, this NSMutableArray is passed to the controller, which in turn passes it to the view, thus displaying the circles.
My question is that if I am to implement the MVC paradigm correctly, should :
The Model (myModel) hold instances of Circle, or the instances of Circle should be held by the controller?
My model be made of 1 class, or is it legal to be made of several classes?
The model know the bound size of the view or is that something that a violation in the MVC philosophy?
One last question. If I have made the implementation as I have stated above, are myModel and Circle separate models or both classes constitute one model?
Thank you!
[Should] The Model (myModel) hold instances of Circle, or the
instances of Circle should be held by the controller?
The model should hold the data. That's it's job. Imagine what would happen if you wanted to change the interface to your program. Instead of (or in addition to) drawing circles on the screen, you might want to display a list of circles and their locations. You'd might want to change or replace the view controller to do that, but you wouldn't need to change the model that stores the circles. Likewise, you might want to change the way that circles are generated, but keep displaying them the way you are now. In that case, you'd change the model, but the view controller and view could probably stay the same.
[Should] My model be made of 1 class, or is it legal to be made of several classes?
A data model is typically a whole graph of objects, very often of different types. You might have one object that manages the rest (although you don't have to). For example, your MyModel class contains an array that stores Circle objects. You could add Square objects, Group objects, etc.
[Should] The model know the bound size of the view or is that
something that a violation in the MVC philosophy?
The model shouldn't know specifically about the view, but it's fine for the view controller to tell it to produce circles within a given range of coordinates. That way, if the view changes size or orientation, the view controller will likely know about it, and it can in turn give the model new info.
If you have other components to your model than just circles, wrap everything in myModel. Even if you don't, you might still want to do so to allow for future additions.
Depends on your design. If you are writing a "document based" application (regardless of whether you are using UIDocument) you normally would have a single class that contains the others. Even if you aren't, having a single root class for archiving purposes, etc., is usually convenient.
The model should definitely not know anything about the view hierarchy. (Note that this is different from knowing something like "canvas size" - it would be legitimate to store such a property in the model, and let the view display the canvas however it wishes, such as in a UIScrollView.)
Btw, kudos for thinking about this ahead of time!
In MVC the View shouldn't hold it's data. However I know in Objective-c you do: [textField setString:#"hello"];, that string is then retained by the text field. The same applies for the textField's font and text colour, etc.
However a UITableView uses a datasource to ask a controller for it's data, it's then up to the controller to reload the table view. But it also stores some data itself, like background colour.
I can understand a reason as to why a UITextView doesn't use a data source the code would become much more lengthy, if every property had to be a method. But why use a data source in some cases and not others, why not just set an array of UITableViewCells (I know that this means cells could not be reused and so it would use more memory, but what other design reason is there), for the UITableView to display?
And when creating you own objects how do you know when to just store a small amount of generic data (e.g. the string a textview displays can only be a string, but any the string itself can be anything)in a view, or use a datasource?
MVC is a pattern, not an edict. Let the view do the work. Some coupling is just going to happen. Follow the guidelines of the pattern, and bend it to the style and desires of your developers and organization.
I'm not familiar with objective-c's mvc framework, but I think I understand the question.
Basically, you don't want the view doing anything with the datasource backend, that is, anything having to do with the plumbing of accessing the DB.
But its ok for the view to have access and use the data itself. That is the M part of MVC. The model gets passed around. The view knows how to display it. The controller knows how to do the business logic to it (including interacting with backend systems like the data access layer).
In the case of data grid, it has to hit the backend to get the data, so it has to rely on the controller.
Ideally, the view knows only about display related information (like the background color). The whole idea being separation of concerns. You want the view to handle just its part of things, like-wise the controller. Then you can modify them independently of each-other.
As for the specifics of the datasource (versus an array), grids tend to be complex. Maybe that is handling paging or other niceties. In this case, I don't think its so much the separation of layers (since an array could just as easily be the model), but handling more functionality.
I'm not sure what you mean re 'storing' small amounts of data in the view. The view should tend to deal with 'view stuff'.
I have a project that will have a lot of views (20 in total). They are displayed in sequence and the user makes certain decisions before tapping a button to make the next view appear. When all 20 views have been displayed, it goes back to the first view.
I also need to create a lot of instances of 3 different objects. So there may be 40 different instances of object1, 20 of object2, and 30 of object3. Each view needs to know about all of these instances and will often change instance variables.
I need to pass these instances between the views. I think I will do this by passing a pointer along to the next view. My question (I've finally got there), is where to create all these instances in the first place? In the original View Controller? Or in the AppDelegate?
Many thanks for any pointers (pun intended)
Usually you'd use CoreData for this. You start creating objects in initial view controller. Then after user manipulates the object you pass that object into next view controller (probably via UINavigationController) and create appropriate objects there as needed and so on and so forth.
On a side note - please rethink your navigation flow and user experience. User might be tired enough after as little as 5th configuration view.
Think MVC
When designing the model, consider diferent aproaches: CoreData, serialization in filesystem, in memory using singletone...
And remember: load lazily