views:

653

answers:

2

Hi

I have this concrete problem, but if You find my initial design idea crazy and have a better suggestion, please let me know:)

I have a UIView that acts as a container/background for adding other views. The important thing is that only one view is present at a time. So before doing any adding of views I do this:

        for(UIView *v in [self.currentView subviews]) {

        [v removeFromSuperview];
    }

self.currentView is the view I add my subviews to.

After this I add a new UIView in this manner:

        UIView *tempView;

    switch (self.currentIndex) {
        case 1:
            tempView = [[AView alloc] initWithFrame:frame];
            [self.currentView addSubview:tempView];
            [tempView release];
            break;
        case 2:
            tempView = [[AView alloc] initWithFrame:frame];
            [self.currentView addSubview:tempView];
            [tempView release];
            break;
        default:
            break;
    }

This way I remove all views, since I release the tempView straight after I add it to the self.currentView I end up with a retain count of one on the the UIView currently living in the currentView.

This all seems fine, but as I look at it with Instruments I can see that each time I run the above code a new AView object is allocated and the old one keeps hanging around with a retain count of 1, either I am missing some obvious retain action being performed on my object or else the "removeFromSuperView" does not call "release" on my view.

In real life my objects are not of type AView, but of many different types, but this way I can test if there is always only one AView instance allocated.

As I can read from the documentation "removeFromSuperView" should call "release" on the view so I am a bit confused as to why my Views are not deallocated.

Again, maybe I am going about this the wrong way and suggestions are really welcome. The setup is that there is a number of button at the bottom of the screen and when the user clicks on the view changes.

Thanks for any help or pointers given:)

+1  A: 

You are iterating a collection and simultaneously changing it

Try

    while ([self.currentView subviews].count>0) {

    [[[self.currentView subviews] objectAtIndex:0] removeFromSuperView];
}

instead.

martinr
This was to big a mouthful for cocoa: while ([self.currentView subviews].count>0) { UIView *v = [[self.currentView subviews] objectAtIndex:0]; [v removeFromSuperview]; }worked better.But still the number of AViews allocated rises.I started Instruments/Object Allocation. ticked the "Created and Still living" and then I ran this code continuously, what could be wrong?
RickiG
Surely you want to audit the retain/release list using Instruments and look at the stacks to see what objects are locking your AViews down? I seem to remember Cmd+E is useful in bringing up this info in Instruments. If you've not used the feature before, try creating some trivial test NSObject subclasses for comparison so you can compare what the audit trail list looks like for a full release and for a failed one [retain>0)? WHat are you are seeing, Ricki?
martinr
I updated my Xcode to version 3.2.1 and now it seems the subviews are truly released using removeFromSuperView. Maybe there "was no spoon" and Instruments simply didn't get it right.I also ran the static analyzer and I would guess it would pick up on a potential problem of this sort right away. But it came back clean, so I'm confident there is no leak.Thanks again for your input:)
RickiG
A: 

you could try the "bringSubviewToFront" and "sendSubviewToBack" functions instead of creating a new UIView everytime. That ways, you won't be creating uiviews for every action and therefore be less pressing on the memory consumption of your application.

learner11
Hi learner11, thanks for the input.I have a scrollView with X pages, each of these pages can contain Y of the above views. This means that if I have 10 pages and 6 of the above view (pages in the X direction of views in "Z" direction). The user could potentially have 60 views in memory at a time. This is the main reason I wish to make sure I completely clean up everything. This way a user can load in max 10 x 1 views and scroll between them without doing any loading. This is well within the memory Im willing to tie up here.
RickiG