I've created a basic NSObject class that defines a particle effect. The class contains some basic float values, and a UIImageView object that represents the particle graphic itself.
When, in the main program, I want to create a new particle effect, I would do so thusly:
I'm having some trouble working out how to correctly dispose of the class once I'm finished with the particle? Inside the particle class, there's some animation stuff done, after which time it runs some code like this:
Which all works great. However, watching the memory profiler - I can see that the memory for the image is disposed, but there's still a single allocation remaining (presumably for the class the ImageView belongs to), and I'm not sure how to remove it?
I was toying with the idea of just pushing new Particles instances into an NSMutableArray which gets crawled every few cycles, and any particles with the 'Dead = YES' flag set are popped from the array.
Why would you say my code is not very MVC compliant? Adding views as subviews of another view is quite a normal thing to do, and there's no memory leaks etc. with any code I've done in this manner.
You said that it's a "basic NSObject class that defines a particle effect" - from your description, that sounds like a model class.
In proper MVC style, a model class should not be referencing/retaining a view.
Ok, fair comment. I just didn't want the overhead of using a UIViewController object as a single particle. Having an NSObject class that contains just a UIImageView object seemed like a cleaner solution. I've found a way around this, in any case.
When I create a particle, I push the Particle class into a mutable array. Then, in the parent class I have a timed function that periodically checks the array for dead particles and removes them - which immediately deallocs the class and releases the retained view inside.
Seems like a fairly simple setup, and has removed the surplus object allocation problem I had.
Thanks for your input in any case, much appreciated.
Assuming "imgView" is a property with the "retain" attribute, you are retaining it twice. The "alloc" retains it, and setting "p.imgView" retains it.
So you need both the release (or autorelease) call when you assign p.imgView, and the release call in dealloc.
Sorry, I should have been more clear. When I declare the particle, I release it immediately after calling [self.view addSubView.imgView], otherwise I'd have a surplus allocation. Don't worry, I've got my head screwed on with that stuff.
My problem was that there was the object attached to the main view with seemingly no way to release the parent class (thus releasing the image view). I've since plugged the Particle class instances into an NSMutableArray - giving me much more control over releasing them individually.
Just run this through the profiler and all object allocations and memory is cleaned up perfectly once a particle has finished its stuff on screen.
Actually, you'd have an extra retain, not allocation. If you need to keep reference to those particle views you can, as you did, either use an array, but you can also iterate through the subviews (which is a property of uiview) of the view to which you are adding them. There's also the viewWithTag option.