Can someone help me understand this?

Discussion in 'iOS Programming' started by Tander, Jun 12, 2012.

  1. Tander macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #1
    Hey guys,

    So I am busy with the NSDate class and I see there is two ways to write the code.

    Option one:

    Code:
    NSDate *now = [NSDate date] 
    This with the correct NSLog - will print the current date to the console.

    Option Two: ( I hear this the Apple - approved way )

    Code:
    NSDate *now = [ [NSDate alloc] init]
    This prints the same as the first code.

    How does the second code work? And why is it Apple approved?

    I am reading the Big Nerd Ranch book on Object C - and they explain this part - but I still don't fully understand why - can someone elaborate for me?

    Sorry if this is a very newbie question.. :rolleyes:
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    Where did you read that one was "Apple Approved" (and the implication being the other is not)? Both are legal, valid, syntactically correct code but would be used in different ways.

    The first is a convenience method which, as per the memory management rules, returns an autoreleased object. The second returns a retained object.
     
  3. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #3
    In the book it says Apple want it the second way - which is where I got that quote from.

    So if the first code works fine - in what example would i use the second code?

    Appreciate your help on this. :cool:
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    Do you know what the difference between an autoreleased and a retained object is? If not I suggest you ensure you read up on memory management and understand that. As it's the key to understanding the difference here.
     
  5. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #5
    No I don't. :(

    I will read up on memory management in a later chapter of the book.

    Once I have read that I assume this code will make more sense.

    Thank you.
     
  6. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    Hopefully yes. Essentially an autoreleased object will automatically get released (and therefore removed from memory and not be usable any more) at the end of the current itteration of the run look. A retained object (created via an alloc/init pair or copy or explicitly retained) will stick around. If you you create an object via alloc/init, copy ore retain an object it is your responsibility to then release it when done.
     
  7. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #7
    Which book? Title, author, edition?

    Which page? Post the exact quote.

    It doesn't even make sense that "Apple want it the second way". Both are valid, in the right context. Moreover, either one can be changed into the functional equivalent of the other:
    Code:
    NSDate *now = [[NSDate date] retain];
    
    is equivalent to the second, and:
    Code:
    NSDate *now = [[[NSDate alloc] init] autorelease];
    
    is equivalent to the first.
     
  8. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #8
    Thanks for the information guys.

    Here is the quote:

    Book: Big Nerd Ranch - Learn Objective C
    Author: Aaron Hillegass
    Page: 163

    Quote

    Unless I am misunderstanding the author completely here?
     
  9. itickings macrumors 6502a

    itickings

    Joined:
    Apr 14, 2007
    #9
    You probably are, yes. The author points out that you shouldn't separate alloc and init, that's all.
     
  10. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #10
    Yes, you are.

    This is the sentence:
    It is good practice (and the only Apple-approved way) to send both of these messages in one line of code by nesting the message sends:
    Code:
    [[NSDate alloc] init];
    
    What this says is that the good practice is to send both messages in one line of code, by nesting the message sends. This good practice is also the only Apple-approved way.

    The Apple-disapproved bad practice is code that calls alloc and init separately (instead of nesting messages). Example:
    Code:
    NSDate * now = [NSDate alloc];
    now = [now init];
    
    Do not do it this way.


    The posted text says nothing about [NSDate date] being Apple-disapproved, or illegal or invalid in any way. It simply says you can change one to the other.

    Unfortunately I don't see where the text says that this change has side effects. The alloc/init results in you owning the object, while [NSDate date] does not. So it's not truly a one-for-one replacement, and in my opinion is a poor example to show, precisely because of the side effects. Unless a release or autorelease is added later, making that change alone will leak an NSDate object.
     
  11. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #11
    Yes :)

    The author means don't do this:
    Code:
    NSDate *date = [NSDate alloc];
    
    [date init];
    
    Why? Because date should not be used between alloc an init as init sets initial values for internal variables and objects can reasonably expect init to be called before any other method.

    The author did not mean that Apple don't approve of using the convenience methods like

    Code:
    NSDate *date = [NSDate date];
    
     
  12. Ides macrumors member

    Joined:
    Mar 27, 2012
    #12
    Misunderstanding

    You're misunderstanding what the book is saying :). When it talks about being apple approved, it means that apple wants you to call alloc-init in the same line, like this:
    Code:
     NSDate *now = [[NSDate alloc] init]; 
    instead of:
    Code:
     NSDate *now = [NSDate alloc];
    now = [now init];
    
    It's saying apple only approves of using alloc init if they're in the same line together, as in the first code I showed. It's not saying that [NSDate date] shouldn't be used.

    And you should definitely read up on memory management :D
     
  13. Tander thread starter macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #13
    Hey Guys,

    Really appreciate the information and help and now I get that I was reading it wrong. :p

    I assume if I am using ARC ( Automatic Reference Counting ) - I don't need to worry about memory management?

    However for completeness and full understanding, I will read up on it.

    Regards
    Robert
     
  14. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #14
    I would stick with learning memory management so you get it. I was lucky enough that when I started ARC was not out and had to track down memory leaks manually. This made me more aware of what it means to own objects and release them when you are finished with them.

    There is a downside to ARC though. There are classes out there that you can download and use in your projects that were not written with ARC in mind. I found this class on line to help me more easily work with web servers (ASIHTTPRequest.h). But found out after trying to compile it would not work with ARC.
     
  15. xStep, Jun 14, 2012
    Last edited: Jun 15, 2012

    xStep macrumors 68000

    Joined:
    Jan 28, 2003
    Location:
    Less lost in L.A.
    #15
    You just need the incantation to solve this minor issue, assuming manual reference counting.

    For your target, find the source name in the build list and add a flag. I think -fno-objc-arc. I'll check that when I'm back in Xcode.

    EDIT: to add the flag per file, click on a target, choose Build Phases, open the Compile Sources drop down pane, double click a file of interest and enter that line above into the popup box and hit Done.
     
  16. jnoxx macrumors 65816

    jnoxx

    Joined:
    Dec 29, 2010
    Location:
    Aartselaar // Antwerp // Belgium
    #16
    Instead of flagging all your code with the no arc tags, it's better to create a '.a' lib of your code and import it as a library, for example, there is a script in the FBConnect library which does just this, so you just need the headers and A lib to import. Then you can use it too, but you can't adjust it.
    The flagging works perfectly, but for clients projects I just like to keep them seperated :)
     
  17. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #17
    I suspect Apple wants to encourage the use of ARC, so they advise the use of alloc/init over convenience methods because ARC will handle those cases more efficiently and with less memory overhead than autorelease pools would.
     

Share This Page