0

I came here to ask for help because I'm on my way to finishing my iphone project and I want it to be perfect!

I have some issues with allocation and deallocation of a UIViewcontroller.

Let me explain :

I have a UITableview with custom cells. In each custom cells, a button that will allocate a new UIViewController : ListOfAGuestFriendViewController;

So, I've made a delegate which calls a method to make a "flip transition", and show my new ListOfAGuestFriendViewController view.

My problem is, and I've gotten the same problem with ALL of my addSubiew, that ListOfAGuestFriendViewController never get deallocated, or gets deallocated just after the view loads!

Can someone explain me exactly how I can make a perfect addSubview ?

Here's my code :

When i flip the view :

-(void)flipAView
{
    Guest *currentSelectedGuest = [self createAGuestUsingIndexPath:self.selectedIndex];

    ListOfAGuestFriendViewController *listOfAGuestFriendViewController = [[ListOfAGuestFriendViewController alloc]init];

    [listOfAGuestFriendViewController setCurrentGuestSelected:currentSelectedGuest];
    [listOfAGuestFriendViewController setMyListOfContactControllerDelegate:self];

    [UIView animateWithDuration:0.25 animations:^{
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight 
                           forView:self.tableviewContainerView cache:YES];
        [self.tableviewContainerView addSubview:listOfAGuestFriendViewController.view];
    }completion:^(BOOL finished){
        [listOfAGuestFriendViewController release];
        [self collapseCurrentExpandedCell];
    }];
}

When i want to go back :

-(IBAction)goBackButtonGotPressed:(id)sender{
    [UIView animateWithDuration:0.5 animations:^{
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft 
                           forView:[self.view superview] cache:YES];
        [self.view removeFromSuperview];
    }];
}

If I remove that line of code :

[listOfAGuestFriendViewController release];

My listOfAGuestFriendViewController never deallocates.

I don't use properties for this instanciation, but when i do, it's the same!

John Conde
  • 217,595
  • 99
  • 455
  • 496
Pwyll28
  • 3
  • 4
  • Obviously your app is not ARC based. Why not convert it to ARC. Many if not all of these memory management issues just go away. When you want to release or dealloc some property or ivar, you just set it to nil. – David H Jul 24 '12 at 17:58
  • I don't really like ARC for now... And converting ALL my project in ARC would take too much time... I have an other project to work on :( – Pwyll28 Jul 24 '12 at 18:03
  • i think your question is when you add this line [listOfAGuestFriendViewController release]; the dealloc works, and if this line [listOfAGuestFriendViewController release]; removed then dealloc never works, is it ? – Midhun MP Jul 24 '12 at 18:12
  • If i remove that line of code : [listOfAGuestFriendViewController release]; The dealloc method is never called, but if i don't, the dealloc method is called just after the viewDidLoad – Pwyll28 Jul 24 '12 at 18:13
  • @MidhunMP The -(IBAction)goBackButtonGotPressed:(id)sender{} method, is called in my listOfAGuestFriendViewController, when i click on my goBackButton! That method must flip listOfAGuestFriendViewController.view back and deallocate my listOfAGuestFriendViewController – Pwyll28 Jul 24 '12 at 18:21
  • @Pwyll28: no dude, it will cause only a memory leak if you won't add this line`[listOfAGuestFriendViewController release];`. – Midhun MP Jul 24 '12 at 18:43
  • @Pwyll28: first important thing is an **object will be deallocated when it's retain count becomes 0**. If you write like object = [[class alloc]init]; it's retain count is 1. If you don't call `[object release];` it never deallocates, instead becomes a memory leak. – Midhun MP Jul 24 '12 at 18:46
  • I know, i've understood that :) – Pwyll28 Jul 24 '12 at 18:55
  • @MidhunMP BUT, even if i let that release line (which i totally say that it MUST be there) there's a problem, my uiviewcontroller is AUTOMATICALLY deallocated! I just click on my button, the view flip and then deallocated! Look : http://youtu.be/P0Jq-zQNsdw – Pwyll28 Jul 24 '12 at 18:57
  • @MidhunMP did you see the video ? I really can't explain why this happens! – Pwyll28 Jul 24 '12 at 19:07
  • @Pwyll28: Yes, i saw. Now i'm researching on that issue. :) – Midhun MP Jul 24 '12 at 19:09
  • @MidhunMP Great thanks! I feared that you could never understand my sooooo bad English ! – Pwyll28 Jul 24 '12 at 19:12

2 Answers2

1

Let me explain with your code:

ListOfAGuestFriendViewController *listOfAGuestFriendViewController = [[ListOfAGuestFriendViewController alloc]init];

When you create an object the retain count will be 1.

When you do this: [self.tableviewContainerView addSubview:listOfAGuestFriendViewController.view]; the receiver view will retain the view. Then it's retaincount will become 2.

After this: [self.view removeFromSuperview]; retain count will become 1.

Every object will be deallocated only after it's retaincount becomes 0. In the above case it's 1, so it never call the dealloc method.

If you write this line: [listOfAGuestFriendViewController release]; after this [self.tableviewContainerView addSubview:listOfAGuestFriendViewController.view]; That means it's retain count is decremented from 2 to 1, so when you call the [self.view removeFromSuperview]; your view will be deallocated. Reference for addSubview Reference for Memory Management

Midhun MP
  • 103,496
  • 31
  • 153
  • 200
  • That's what i thought! But i don't know why, when i do that! The dealloc method in listOfAGuestFriendViewController is called just after the view is loaded! – Pwyll28 Jul 24 '12 at 18:32
  • When you remove the `[listOfAGuestFriendViewController release];` from your code, the object's **retain count** becomes 1, then the dealloc won't be called untill the retaincount becomes 0. – Midhun MP Jul 24 '12 at 18:35
  • did you got it, or still have the issue ? – Midhun MP Jul 24 '12 at 18:38
  • Yes i still have it, i didn't changed anything in my code... My listOfAGuestFriendViewController is deallocated just after the viewDidLoadMethod – Pwyll28 Jul 24 '12 at 18:41
  • @Pwyll28: check this link, in this also, they says dealloc will be called only atlast. http://stackoverflow.com/questions/2261972/what-exactly-must-i-do-in-viewdidunload. I'll find the exact answer and surely pass it to you :) – Midhun MP Jul 24 '12 at 19:24
  • i don't understand, the retain count, is NOT even at 0 after the [listOfAGuestFriendViewController release]; Look : https://skitch.com/pwyll28/ee1hx/ivent.xcodeproj-listofcontactviewcontroller.m – Pwyll28 Jul 24 '12 at 19:59
  • It seems that your [listOfAGuestFriendViewController release] is causing your view to immediately disappear. May be you should try to call it right after your controller animation finish. I think the goBackButtonGotPressed should just call a delegate method on his parent. It is not the job of the listOfAGuestFriendViewController itself to remove from his superview. The parent could right after the back animation, remove the viewController and deallocate it. – adriendenat Jul 24 '12 at 22:02
  • Absolute retain counts are meaningless. Retain count can never be zero. – bbum Jul 24 '12 at 22:58
0

Did you checked the dealloc function ? // Tu as une fonction dealloc dans tes ViewController qui est appelée automatiquement quand ta vue est retirée.

- (void)dealloc
{
    [yourThings release], yourThings = nil;
    [super dealloc];
}
adriendenat
  • 3,445
  • 1
  • 25
  • 25
  • Yes, i've checked it! I've put a breakpoint in my dealloc function! If i remove that line of code : [listOfAGuestFriendViewController release]; The dealloc method is never called, but if i don't, the dealloc method is called just after the viewDidLoad – Pwyll28 Jul 24 '12 at 18:09