Issue in lazy loading the table view - objective-c

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.

Related

MVC: Controller keeps array of model objects or view objects?

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"

Where to create my objects? Multiple views in project

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

NSTableViewDataSource or NSArrayController?

I need to load data dynamically as a user scrolls through an NSTableView. For example, the table might display 50 rows, and as it scrolls further I need to fetch more data from the network. The number of of objects/rows is known beforehand, so I want the table to have the right number of rows from the start, but showing empty cells while data is loading.
I'm using Core Data so it's easy to connect the table to my model using bindings. This would also take care of cells being updated as data comes in and is parsed. I've tried to figure out how I could do this by subclassing NSArrayController but from what I can tell there is no information flowing from the table to the controller about which rows actually need data. Therefore, I'm thinking of implementing NSTableViewDataSource instead, where I can easily check if the table has scrolled beyond the rows for which data is available. On the other hand, I don't know if I will get cells automatically updating as easily with this solution.
In case anyone comes across this, here's my own answer:
Yes, you need to implement NSTableViewDataSource on a controller, observe changes on the data and call reloadData manually on the table when changes occur. The main reason for doing this is that you can defer loading of data until it's actually needed (when the table view scrolls). Using the data source protocol keeps you informed of which indexes are requested.

How do I keep track of the data represented by a view?

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.

Core Data: When and where are Entities loaded in the first Place?

I have a question about Core Data. When starting my appliction, when is my data (which is stored automatically by Core Data) loaded into the NSArrayControllers? I want to modify it in the first place before the user can interact with it.
To be more specific: I have an NSArrayController for the entitity Playlist. Before the user can add new playlists or interact with the app at all, I want to modify the playlists programmatically. I tried windowControllerDidLoadNib: in my NSPersistentDocument (MyDocument.m) and awakeFromNib both in my NSPersistendDocument and the NSArrayController, but when I check in these methods with [[myArrayController arrangedObjects] count] I get 0 as result (the array controller's content is empty).
However, I actually have data stored and it is displayed to the user. I just do not know when and where I can modify it in the first place.
Thank your for any help.
Data is never "loaded" into the NSArrayController. The array controller is not an array itself. It does not contain or otherwise store data.
Instead, the array controller queries the object it is bound to for specific pieces of data only when that specific data is needed. This is especially true of Core Data in which managed objects are only fully instantiated when their attributes are accessed. The array controller moves data from an array type data structure to another object (usually an UI element.)
If you want to modify an existing store before it displays in the UI, you need to process the data before the array controller used by the UI is even initialized. If you're using NSPersistentDocument, then you can override readFromURL:ofType:error: to fetch and modify all your objects when the document is first opened. Alternatively, you can override the window controller's windowWillLoad or showWindow methods.
Regardless of where you do it, you must fetch all the managed objects you want to modify. You could programmatically create an array controller to do this but a fetch request is easier to micro manage if you have a large number of objects to modify.
You could try observing the "arrangedObjects" keypath of the controller and adding some logic to work that your array controller has been populated for the first time.
Another possible hook is implementing the awakeFromInsert/awakeFromFetch methods of your managed objects.