Is there an error in "View Controller Programming Guide for iPhoneOS" document?

Discussion in 'Mac Programming' started by bengimizrahi, Jun 3, 2008.

  1. bengimizrahi macrumors newbie

    bengimizrahi

    Joined:
    May 24, 2008
    Location:
    Istanbul
    #1
    I have been reading this document but I am stuck on page 34. Could you please check if this code fragment leads to a memory leak?

    Code:
    - (id)initWithNibName:(NSString*)nibNamebundle:(NSBundle*)nibBundle 
    color:(UIColor*)color 
    {
        self=[superinitWithNibName:nilbundle:nil]; 
        if(self){ 
            _color=[colorcopy]; 
            self.navigationItem.prompt=@"Justacolor..."; 
            UIBarButtonItem*anotherButton=[UIBarButtonIteminitWithTitle:@"Show" 
                style:UIBarButtonItemStylePlain 
                target:selfaction:@selector(showAnotherClicked:)]; 
            self.navigationItem.rightBarButtonItem=anotherButton;
        } 
        return self; 
    } 
    
    Shouldn't there be
    Code:
    [anotherButton release];
    just after
    Code:
    self.navigationItem.rightBarButtonItem=anotherButton;
    ?
     
  2. iSee macrumors 68040

    iSee

    Joined:
    Oct 25, 2004
    #2
    Heh, why don't you try it out and see what happens? ;)

    That code's hard to read--it looks like spaces have been stripped. But if I'm reading it right, then the code looks OK.

    [UIBarButtonItem initWithTitle...] creates an object with a ref count of one.

    A pointer to the object is stored at anotherButton.

    Then a pointer to the object is copied to self.navigationItem.rightBarButtonItem

    Then anotherButton goes out of scope, leaving one pointer pointing to the object and the object having a reference count of one.

    The code could have incremented the ref count when a pointer to the object was copied to self.navigationItem.rightBarButtonItem, because at that point there were two references to the object. And then it would have had to decrement the ref count when anotherButton went away. But they decided to shortcut those steps. In such a short bit of code, I'd say that's OK.
     
  3. tacoman667 macrumors regular

    Joined:
    Mar 27, 2008
    #3
    If I am off let me know. If you do not dealloc the object then the retention count doesn't matter if there is 1 or 0 left. it can be have 1 retention but at dealloc it will not release the memory. it can have a count of 0 but if you do not dealloc then it will still be allocated for the life of the owning object. Garbage collecting doesn't grab objects as soon as they are counted 0, it is on a cycle and the next time it ticks is when it checks for counts and deallocates the ones with 0 counts.
     
  4. therevolution macrumors 6502

    Joined:
    May 12, 2003
    #4
    What throws me is the fact that they are using an 'init' method without calling 'alloc' first, as in:

    Code:
    UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:...];
    
    If alloc was there, then I would agree that the code is leaking. But since it's not, I'm not sure. I thought you had to call 'alloc' before using an 'init' method.
     
  5. tacoman667 macrumors regular

    Joined:
    Mar 27, 2008
    #5
    Only if you want to regulate garbage collection yourself. If you let the new garbage collector handle retainers then you only need to use init. This only works for Obj-C 2.0 classes or classes converted to 2.0.
     
  6. therevolution macrumors 6502

    Joined:
    May 12, 2003
    #6
    Ah. Got it. I am new to Objective-C and writing code for the iPhone, which does not support GC.

    I guess that answers the original question: no, it does not leak, because the garbage collector will take care of it.
     
  7. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #7
    Its not an init method as it doesn't contain the word init, its a + method, like [NSString stringWithFormat:mad:"blah"]

    and so the pointer will be auto-released.

    So back to the OP the code on Apple's website is correct and won't memory leak :).
     
  8. iSee macrumors 68040

    iSee

    Joined:
    Oct 25, 2004
    #8
    "initWithTitle:..." is the method (I think--it's hard to tell with the spaces stripped), so it *is* an init method.

    As therevolution pointed out, there should be a call to alloc, though. That's a bug.

    But, yeah, I take back what I said before. This code probably does leak, even once the call to alloc is added. Before, I didn't realize that rightBarButtonItem is almost surely a property that will retain the object for itself when the assignment is made. If it's actually a regular, dumb pointer then there is no leak.
     
  9. fredfnord macrumors regular

    Joined:
    Sep 9, 2007
    #9
    initWithTitle isn't an init method, as it doesn't contain the word init.

    Riiiight.

    -fred
     
  10. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #10
    I see the point. To be honest I don't think the code will work until an alloc is added, and then unless an autorelease is added it'll leak.
     
  11. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #11
    Yeah, I missed that :eek:.
     
  12. therevolution macrumors 6502

    Joined:
    May 12, 2003
    #12
    I think we figured this out, guys - this code sample is an example of Obj-C 2.0 with garbage collection enabled. It means two things with regard to the sample:

    1. When using GC, there's no need to call alloc before init.

    2. There's no need to release, even if you use init. The GC will clean it up.

    That said, it is weird they'd use a code sample that uses GC for an iPhone-specific guide, as garbage collection is not available to iPhone apps.


    Edit:

    You know, after searching, I can't find documentation on any 2.0 features that let you omit 'alloc'. tacoman667, are you sure that's right? Can you link to anything that documents that behavior?
     

Share This Page