Question

EDIT

I found out that my screens don't get nil because they keep RefCt but my question is why isn't the RefCt 0? I simply create, add and remove the view. Also added a screendump of instruments:

Screendump of Instruments

So you see at the beginning

Malloc 1 initwithframe, retain: 2 initwithframe, release :1 -[UIView(Internal) _addSubview:positioned:relativeTo:], retain : 2 Quartzcore CALAyer layoutSublayers, retain: 3 Quartzcore CALAyer layoutSublayers, release: 2 Then in my code I remove this view, removeFromSuperView: 1

Can somebody explain this:

 -[UIView(Internal) _addSubview:positioned:relativeTo:], retain : 2

line? I think this is why my view still has a RefCt.

END

Im trying to clean my code and eventually speed up my app but I dont think i really get the whole memory management thing. Basically my app has one view visible for the user but it can switch to a different view depending on what the user selects in the menu. Now I think the most logic is that only one view at a time should be allocated and taking up memory space and when a user selects another view the current view should be released and the selected view should be allocated. I tried to create this by doing something like this when selecting a new view:

- (void)removeMenus {
    @autoreleasepool {
        for (UIView *view in container.subviews) {
            NSLog(@"View to be removed: %@", view);
            [view removeFromSuperview];
        }
    }
}

Lets say the user chose to show the startscreen again. This bit of code will run:

- (void)createStartScreen {
    if (startScreen == nil) {
        startScreen = [[StartScreen alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
        startScreen.delegate = self;
        startScreen.layer.shadowColor = [[UIColor blackColor] CGColor];
        startScreen.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
        startScreen.layer.shadowRadius = 5.0f;
        startScreen.layer.shadowOpacity = 1.0f;
    }
}

I put a breakpoint there and discovered startscreen isn't nil while I thought it should be because I removed it from the superview (also tried nilling out the pointers of that var). If I understand this correctly startscreen's retain count isn't zero right? Also I'm using ARC so I thought ARC would handle this nicely.

What is the correct way of releasing views which aren't visible anymore to the user to preserve memory?

Was it helpful?

Solution

This depends on what the ivar startScreen is. If startScreen is defined as a strong ivar in your view controller, then it will have a refcount of 1 after allocation, and a refcount of 2 after you set it as a subview in your view hierarchy. Then, removing the view from its superview will only reduce the refcount to 1 and you'll have to explicitly nil the variable to dealloc it.

Another option is that your view is defined in a Storyboard or a XIB file and is connected to your view controller via an outlet. In that case, your view ivar must be set as a weak variable since it's already being held strong-ly by someone else.

Read about the differences between strong and weak qualifiers here.

Last thing - for better readability, it's a common convention to define a property over variables you want to lazy instantiate, then put the code you've written inside createStartScreen in the overridden getter method.

OTHER TIPS

If you would like more visibility into what's preventing your view from being released, you should Profile your app using Instruments' Allocations template. This will tell you the call site of every retain and release, including those performed by ARC and the system frameworks. If your views are being instantiated from a XIB file, to a certain degree, the system frameworks control their lifetimes.

The next piece of sage advice I can offer is to stop thinking about absolute retain count right now. Just pretend the -retainCount method doesn't exist. Really. I'm not kidding. Others with far more authority than I have explained the details of why retain count is useless, so if you won't take my word of it go read this.

All that said, I don't have enough information to be sure, but typically excessive memory use is not due one or two views that haven't been released. Instruments can give you a window into what your real problem is.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top