memoryWarning in Objective-c - objective-c

I have an application with lots of view, about 20, accessible from two main menus, in each view there are labels, textfields and buttons, over a background image.
As data i've a global class and some array filled by xml files.
If memoryWarning fires, I should release what is not necessary, but if you are in one view, all in the other view is already deallocated right? What should I deallocate? Removing the global class i will lose essential data, the same for array.
Suggestions? (Sorry for bad english).

The views you have left are not necesserily deallocated, it all depends on the code. So you possible hold everything in the memory at the same time and memory is a scarse resource on iOS. So if you have a lot of views deallocate those that you don't currently use.
After receiving memory warning you should remove everything that you not need. Keep an eye on those XML files in arrays, XML files tend to be big: as the source and as a DOM tree in the memory after being parsed. You can try to make them all being lazy loaded and parsed, throw them away if not more needed, reload if needed again (you have then to save their loading state, nut this could be a simple array of boolean value instead of whole XML data).

Related

Multiple instances of an object inside a XIB file

I have a document-based app with the recommended NSDocument / NSWindowController setup. Every window has its own NSWindowController instance and an associated XIB file. The interface is loaded pretty straight-forward in -(id)init: if (self = [super initWithWindowNibName:#"DocumentWindow"]) { // yadda yadda }. The XIB file contains an object that represents a separate controller that should be instanciated every time the user opens a new window. It presents data that is only relevant to the current document. When I unpack the object with -(id)initWithWindowNibName: I always get a reference to the same instance despite having two different window controllers and despite having called -(id)initWithWindowNibName: twice. The XIB loading mechanism seems to only unpack the same archived object once which kind of makes sense (really?).
Is there no way besides allocating separate objects in code, manually loading views, calculating their sizes, adding them as subviews, then setting bindings and keeping an eye on unbinding them manually when the window gets closed?
I’m banging my head against the wall, because of my own stupidity. It just makes things worse.
As I initially thought I was absolutely on the wrong path. The issue was simply that I registered a notification in the aforementioned instantiated class for an object that was a subview of the application’s keyWindow (I hacked it together and wanted to change it later to a property, ouch). When the application was loaded all instances registered for all document windows and all of them got notified and calculated the same data.
The debugger is my best friend today.
There is actually nothing like an optimization when you unarchive objects from a XIB and you will always get different instances (which absolutely makes sense in retrospect). If you encounter a similar issue, then it’s probably an unrelated bug at another place in your code.

Loading NSTableView Lazily

On iOS, an NSTableView (UITableView) is loaded lazily, in the sense that the table only displays the cell that are needed for the current view and not more. As the user scrolls up or down, more information is loaded from the data source.
Is there something similar for OSX? I have an NSTableView with 1000+ records to load (+multiple columns) which is resulting in laggy loading as well as lag when scrolling up or down.
Would this 'lazy' loading be a good solution(if possible)? Or maybe something along the same lines?
Thanks.
P.S. Regarding the loading process - I use the two usual methods
-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
and
-(NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
to load the data. Within them there are if statements to check some variables, since I have 2 combo boxes that contain data, that when containing "ALL" and "ALL" load these 1000+ records. If the combo boxes are not "ALL" and "ALL", then only a couple of records are loaded, which load just fine.
I think the problem, given that you have explained that lazy loading is done automatically, is that I am loading the data from XML files, so maybe the parsing is taking up a large chunk of processing time.
I though of loading the data from the XML file into an NSDictionary at runtime and keeping it in memory, available for use when needed, so that I can avoid the loading time when the information is actually needed to display.
What do you think? Thanks!
You definitely want to cache your XML file into some sort of data structure. The tableView:objectValueForTableColumn:row: method will be called once for every visible cell. If you have a lot of columns, it's easy to have 200 cells visible. Page down, and those cells all change, your XML file loads 200 times, and you get laggy scrolling.
Even if the XML file is only loaded and parsed for every cell in a specific column, it will be slow and should be fixed.
You can verify that the caching is necessary by making tableView:objectValueForTableColumn:row: return nil where it would otherwise parse the XML file. Once you make this change, does it scroll smoothly, or do you have other problems? It would obviously make the application unusable, but you should always check if an optimization is necessary and sufficient before implementing it.

Fundamental Drag And Drop In iOS

I've been considering an app now that implements a drag and drop sort of idiom from maybe a side pane or a drawer, etc. what I can't wrap my head around are how to keep reference to the objects I drop. I mean; it would be easy if it was just drop the object, then let it alone, but I want more manipulation after the fact.
My brain just cannot wrap around the concept of creating objects out of thin air to place on the 'canvas', or having preset objects (which I imagine would be limited, cumbersome and awkward) already on the canvas that would then just be activated and manipulated easily, seeing as the references to them are created before the fact (my apologies for the loose term 'reference', I mean something like selecting the object and having it's unique properties recognized or displayed).
There must be something I'm missing. So, I wonder how one might go about implementing drag and drop with interface and manipulation with the dropped object after the fact or maybe sample code or a link to a git or svn repo? (something like how MIT's scratch, or Xcode's interface builder might work).
For clarity's sake, I know how to go about fiddling with drag and drop thanks to DragKit, but not about editing 'properties' on the object dropped onto the 'canvas', and I would like there to be a near infinite amount of objects that can be dropped on the canvas, yet a set amount of items in the drawer/side view.
If I'm understanding your question correctly, you want to be able to drag objects onto a canvas and then manipulate their properties individually. For instance, you'd drag square views onto the screen and then increase its size or change its color.
In order to do something like that, I would have a NSMutableArray or an NSMutableSet that would hold all of the on canvas objects. Then when any interaction comes, you could either dynamically generate gesture recognizers if the objects are UIViews or a subclass. Then in the target of the gesture recognizer you would use the recognizer.view property.
Or you would have to check which object on the canvas you were currently manipulating. That would be done by iterating through the array and seeing which object equals the one you are touching.
Is there anything that you are trying to do but is not working? Have you written any code in attempt to do this?

Working with many interface elements in Cocoa

My app requires an interface that has many buttons, text fields and matrixes. And they need to change from time to time. Right now I do this by having all elements in IB already and hiding/showing/moving them when needed. What would others recommend? Should I do that? Should I use an NSTabView? NSView? Should create the elements programatically? If so, what if I have an element that is already created that I need again without changes? It would be a waste of releasing it and creating it again.
Any help would be greatly appreciated.
In my opinion, it's better to create interfaces programmatically if you have to animate views around a lot. If it's just a matter of hiding/unhiding them, IB works great, but if you need re-layout or create unknown numbers of views dynamically it's not worth trying to make it all work with nib files.
As for general advice:
Create subclasses (from UIView or UIControl or one of their subclasses) for every kind of element you're going to use. It's tempting to piece together composite views from your UIViewController, but you'll really be much better off creating real classes.
Study the standard Cocoa view classes, and try to create similar API:s in your own controls and views.
Put as much data (sub-element positioning etc) into a plist, so that you can easily change it from one centralized place instead of having to dig around in the code.
If you are often creating several dozen short-lived views, it's worth keeping them in a pool and reusing them. But if it's just a few labels being added and removed intermittently I wouldn't worry too much about it. As usual: don't optimize too early.
Your current approach sounds fine. If you're showing/hiding them but otherwise they remain unchanged, why go through the trouble of creating them with code, when your XIB keeps a "freeze-dried" copy of exactly what you need already?
As long as you're keeping them within logical groups, you can just move/swap/show/hide the group's container (like NSBox or an NSView). If you have a LOT of logical groups, which aren't always shown every session, you can separate them out into their own XIBs and only load them when they're needed, to save launch time and memory.
If you use NSViewController, it's even better because you can make clean breaks for each logical group. Load the panel as the view and the view controller will keep outlets/actions and has a one-to-one relationship with a xib.

Managing data for UITableViews

I have two very simple, identical UITableViews in my app that are populated with thumbnail images named "thumb1.jpg", "thumb2.jpg", etc. These thumbnails have associated original images "1.jpg" and text files "1.txt" used for image processing. Everything is stored in the app's Documents folder.
I want to keep the numbered, ordered naming for these files since it makes displaying the thumbnails in the UITableViews very easy with cellForRowAtIndexPath. I'm currently using a NSMutableArray (index: 1 object:"thumb1.jpg", etc) to track all images in the app.
The issue is that users can add/delete images so maintaining the order is important. For handling adding/deleting I'm looking at using insertObjectAtIndex and removeObjectAtIndex on the NSMutableArray, which will maintain order but will require programmatically changing image and text file names when this happens. For example, if there are five images in the array "0.jpg","1.jpg","2.jpg","3.jpg","4.jpg" and the user deletes the second image ("1.jpg") the array will now have "2.jpg" at index 1 so filenames will have to be changed to "1.jpg", "1.txt", and "thumb1.jpg".
How does this approach sound? I'm new to Objective-C so if you have other functions you'd use, etc I'd be interested to hear your opinion.
Renaming the actual image files themselves doesn't sound like a good idea.
I would implement 2 NSMutableArrays, one to hold the title/description of the image and one to hold the filename (or, if you wanted, the actual UIImage instead). Then if you need to delete, for example the item at index 2, deleting the same object from each of the two arrays will then leave them in sync.
If you start wanting more and more things to be stored for each row, I suggest you implement your own class. You can then implement an array of multiple instances of that class, and each class would have properties such as image, text, thumbnail etc. In fact, because you've already named three separate properties (main image, text and thumbnail) I'm tempted to say you should implement a custom class straight away.
Let me know if this makes sense or if you'd like some code to further illustrate it.