Brett
Brett

Reputation: 12007

Passing a ViewController to a child view, and then back again fails to release the VC in iOS

I have an issue (related to this SO question). But the root problem is so different than I originally thought, that I need to post it as a new question; but I'll update the previous question to reference this one - if anyone is able to help.

I have a UINavigationController which has vcA as the rootViewController. vcB is then pushed onto the navigation stack. vcB has a child view which is a UIView subclass (call it BSView) with some buttons on it. I need to have vcB be aware of when the buttons on BSView are tapped, so I implemented a @protocol as in the BBView.h as shown below:

@protocol BBViewDelegate <NSObject>
@optional
-(void)buttonAPressed;
-(void)buttonBPressed;
-(void)buttonCPressed;
@end

@interface BBView : UIView {
    id<BBViewDelegate> _delegate;
    NSString *_title;
}
- (id)initWithFrame:(CGRect)frame withTitle:(NSString *)title 
        andDelegate:(id<BBViewDelegate>)delegate;
@end

and the BBView.m init method looks like:

- (id)initWithFrame:(CGRect)frame withTitle:(NSString *)title 
                                andDelegate:(id<BBViewDelegate>)delegate
{
    self = [super initWithFrame:frame];
    if (self) {

        _delegate = delegate;
        _title = title;
    }
  return self;
}

where delegate will be vcB. And when buttonA is pressed, this code is fired:

if(_delegate && [_delegate respondsToSelector:@selector(buttonAPressed)]) {
    [_delegate buttonAPressed];
}

This appears to work fine. All the methods are called as expected. Here is the problem. When I pop vcB back to vcA, vcB is never released. If vcB is pushed again, then the memory just cycles up. I can repeat this cycling until the app explodes.

When I don't init BBView with any delegate variable (or a nil value), the vcB memory is released on a navigation pop. But then of course, vcB is never made aware of the button taps.

Does anyone have any idea what could be going on??? I have been messing with this for a long time now, and I simply can't figure out how to pass in vcB as an object to BBView and have it release when the navigation is popped back to vcA.

Any pointers would be most helpful.

Upvotes: 1

Views: 714

Answers (1)

Dan F
Dan F

Reputation: 17732

Your delegate pointer is creating a retain loop. You should declare the delegate variable as __weak or as a weak property

Upvotes: 2

Related Questions