views:

860

answers:

3

Hi

I build a parsing algorithm using NSXMLParser. Im having doubt as to what is the best strategy for keeping my memory usage on a minimum.

I have a valueObject (e.g. "Person") this object has ≈ 30 NSString properties, while parsing the xml I continually alloc and release a temporary Person object as the nodes are traversed. I checked this and there is only one of these Person objects instantiated at any time. When a node is traversed and a Person is "build" I pass the Person to a NSMutableArray and release this Person. Seems no problem there. (I'll need the array for a tableView). When I reach around 50+ Person objects in the array my app just quits, didReceiveMemoryWarning doesn't get called, no other warnings, no parseErrorOccurred, nothing?

If I limit the number of Persons in xml the app does just fine, I haven't been able to find any memory leaks with Instruments. I think that I simply can't hold 50+ Person objects in an array… seems a bit harsh, but I haven't got much memory experience with the iPhone, so this is just a guess.

The xml is search results from which the user probably only needs a few, so persisting them to my core model to keep them around for display seems a bit crazy.

What would be a good strategy for keeping these Person objects around? or am I missing a huge memory leak since the iPhone should be able to handle much more than this?

Hope some experienced developers can point me in the right direction:)

Thank you!

+1  A: 

How long are those strings? Generally, on the iPhone 3G and older models, your app should have a minimum of about 20 MB of memory available (much more on the 3Gs). This is no absolute rule, of course, but a decent rule of thumb. To occupy this much memory with 50 objects would mean ~400-500 KB per Person object. Is this in the ballpark? If so, you will probably need a memory management strategy that does not keep all objects in memory at the same time. Core Data can probably help you a great deal in that case.

Ole Begemann
Hi OleThanks I was looking for some insight in that manner:) my Person objects are around 0.1KB a piece.Im beginning to think it is the webservice from where I get the data that is acting up. I kept testing with different amounts of xml poured into my script and it did not crash consistently in the simulatorI seems that if I run it with Instruments it will not crash, but just grow to ≈250MB. I believe Nathan is on to something, Instruments can't find any leaks and the moment the parsing is done(and URLConnection and XMLParser is released) allocated MB's goes from 250 to 1.5.Thanks:)
RickiG
I have a core data model in place, but would really think it crazy to have to use that to display 50 search results.I think the bug is buried elsewhere, maybe I should slow down and look better into the Instruments tools.Thanks
RickiG
A: 

If you did not receive a memory warning it is probably not the reason your app is quitting. In Xcode go to the organizer, and select the device, then click on the console tab. If they app was shutdown for memory reasons there will be a system message in the console log saying it is killing the app due to memory pressure.

Louis Gerbarg
As I understand NSXMLParser, `-parse` is a synchronous method, i.e., it doesn't return to the run loop until the parsing process is finished. In such a case, you wouldn't get a memory warning, would you?
Ole Begemann
It depends... Personally I never do XML parsing on the main thread (primarily to avoid the UI hiccuping), so the main run loop continues processing events just fine.
Louis Gerbarg
+2  A: 

Despite NSXMLParser being a SAX-based parser it does not support parsing an input stream, which means that the entire XML string you are parsing is kept in memory. This on its own is a big issue, but as you parse the problem gets worse as you start duplicating the string data from the XML in your Person objects.

If your strings are really big, you've got the second problem of having too many parsed Person objects in memory at one time.

The first problem can be solved by using AQXMLParser from Jim Dovey's AQToolkit library, which provides an NSXMLParser-like API but with support for streaming the data from disk.

The second problem can be solved using a disk-based persistence technology, like Core Data, SQLite Persistent Objects, or even just storing the Person objects on disk yourself.

Nathan de Vries
Thanks NathanThis is mind boggling to me:) I was sure a SAX parser would read a stream and not just a chunk from memory:/ I will try and lok into the ToolKit you recommend, thanks for clearing that misunderstanding about the NSXMLParser up for me!
RickiG
Nathan de Vries