Ok guys I am developing an iPhone app I have a Model class which follows a Singleton design pattern.
Now I have an NSArray in it which is initialized to around some 1000 NSStrings in the init method.
Now I need to use this data in some view controller. so I import Model.h, I create an array of NSString objects in view controller & set the data to it. But now the problem is that now I have 2000 NSStrings currently allocated, which I believe is not a good thing on iPhone due to memory considerations.
releasing model object wont help because I've overrided release method to release nothing according to the pattern & I cannot change the design now because now a lot of code works on the assumption of model being a singleton.
& in future maybe the initial NSStrings may grow to 2000 or even开发者_如何学运维 more & then I'll have 4000 NSStrings allocated at one time ....
I am a little confused on how to go about it any suggestions
A few thousand strings take barely any memory at all. 4000 strings would take a couple of hundred kB, depending on length. (Rule of thumb here is string length + 20).
Edit: Probably more like string length + 30 or 40, actually; I'm not certain how much overhead NSArray adds.
Reedit: Given the information from the below question; you could probably get away with loading a few hundred strings at the most; just around the area you are browsing; basically turning your SQLite access into a sparse array that caches a few strings around the search area. Not, of course, that I believe it to be necessary; if the strings are location names they probably have an average byte size of 20-30 bytes; giving a (very) rough estimate of 300k of memory to keep them all in memory permanently, greatly reducing access time and giving a better user experience. The iPhone doesn't have a lot of RAM; but you can afford, at the very least a fair few megabytes; 300k isn't going to break your back.
It's difficult to offer specific suggestions without knowing more about your implementation--where do your strings come from? In general, the best performance optimization for this sort of situation is lazy loading. Here are some examples of ways to have a reduced memory footprint with different technologies if you have a table view:
- Core Data: Not usually a problem, since objects are faulted and fetched automatically.
- SQLite: Again, not usually a problem--you query the database every time you need a particular value (such as when a table view cell needs to display a string).
- Internet: Start a request (usually via a thread) when the table view cell is visible.
- XML: Trickier, but use SAX (event)-based parsing to find values instead of DOM parsing (which loads the entire document to memory).
That being said, if you made design decisions that are difficult to reverse, it may not be possible to significantly reduce your memory footprint without major refactoring.
EDIT: As per other answers, it's probably not worrying about, but if you were to optimize for memory, you would not load all the SQLite values at application launch, but instead fetch each value from SQLite in cellForRowAtIndexPath
. These sorts of problems are made much easier using Core Data--I would highly recommend using Core Data instead of straight SQLite (although it sounds as if you might be too far into development to switch at this point).
If your Model object really is a singleton, then all you need to do is get your strings from the model object in the view controller and use them. I don't see why you would get duplicates.
With NSString, as long as the strings are immutable, the copy method should just retain the object to copy and return the same object to you. Also, if your strings are constant strings i.e. defined like so:
NSString* foo = @"bar";
they are actually part of the executable and will take up no extra RAM at run time.
精彩评论