Question about scope of "convenience objects"

  • I am wanting to use an NSDictionary object to return multiple values
    from one of my methods. As soon as the dictionary object is returned,
    I pull the contents out of it.

    My first thinking was to create it with dictionaryWithObjectsAndKeys:
    then return it.

    But then I got nervous that it would release and dealloc at the end
    of the method, leaving me with an invalid pointer getting returned.

    But upon reading the simple rules at
    http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/
    Tasks/MemoryManagementRules.html

    they say "A received object is normally guaranteed to remain valid
    within the method it was received in...That method may also safely
    return the object to its invoker."

    So it looks like I am ok after all to use my NSDictionaryObject in
    the method that called the method in which the object was created. Is
    this correct?

    Thank you
  • > Is
    > this correct?

    Yes, you've understood the rule. For more info on why, follow the link at
    the bottom of that page and see the section "Creating Objects Using
    Convenience Methods".

    <http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Concep
    ts/ObjectOwnership.html#//apple_ref/doc/uid/20000043-BEHDEDDB
    >

    --
    Scott Ribe
    <scott_ribe...>
    http://www.killerbytes.com/
    (303) 722-0567 voice
  • --- Paul Bruneau <paul_bruneau...>
    wrote:

    > But upon reading the simple rules at
    >
    http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/
    >
    > Tasks/MemoryManagementRules.html
    >
    > they say "A received object is normally guaranteed
    > to remain valid
    > within the method it was received in...That method
    > may also safely
    > return the object to its invoker."
    >
    > So it looks like I am ok after all to use my
    > NSDictionaryObject in
    > the method that called the method in which the
    > object was created. Is
    > this correct?

    In general, yes. There's nothing magic about
    autorelease. The documentation is pretty explicit
    about what makes autoreleased objects go away -- it
    happens when an NSAutoreleasePool is deallocated.

    Cheers,
    Chuck

          ____________________________________________________________________________________
    Fussy? Opinionated? Impossible to please? Perfect.  Join Yahoo!'s user panel and lay it on us. http://surveylink.yahoo.com/gmrs/yahoo_panel_invite.asp?a=7
  • > So it looks like I am ok after all to use my NSDictionaryObject in
    > the method that called the method in which the object was created. Is
    > this correct?

      How do you think dictionaries and arrays of things are handed back
    to you from other Cocoa methods? A hint: the same way. :-) If you
    weren't able to rely on the object being returned sticking around long
    enough for you to at least retain it, nothing would work right.

      I see some prefer the style (on a "getter" accessor method) of:

      return [[object retain] autorelease];

      But the memory management guide says simply returning the object is
    sufficient: "... no need for retain or release:". Given that, I don't
    think that really buys you anything in the general case.

      FWIW, I use the "hand back a dictionary to return multiple values"
    approach frequently. It's (IMHO) a natural use of such a "throw-away"
    container.

    --
    I.S.
  • > I see some prefer the style (on a "getter" accessor method) of:
    >
    > return [[object retain] autorelease];

    In an accessor method, that makes sense for objects that might be shared
    between threads. (And I can think of other situations, but they seem pretty
    contrived.) In the context of the current discussion it adds nothing,
    because the retain/autorelease of the convenience method must have been
    performed in the current thread.

    --
    Scott Ribe
    <scott_ribe...>
    http://www.killerbytes.com/
    (303) 722-0567 voice
  • On Sep 21, 2007, at 11:16 AM, Scott Ribe wrote:

    > Yes, you've understood the rule. For more info on why, follow the
    > link at
    > the bottom of that page and see the section "Creating Objects Using
    > Convenience Methods".

    Thank you.

    On Sep 21, 2007, at 11:20 AM, Charles Steinman wrote:

    > In general, yes. There's nothing magic about
    > autorelease. The documentation is pretty explicit
    > about what makes autoreleased objects go away -- it
    > happens when an NSAutoreleasePool is deallocated.
    >
    > Cheers,
    > Chuck

    Thanks. The reason for my question, though, was that I wasn't sure
    _when_ that would happen.

    On Sep 21, 2007, at 11:30 AM, I. Savant wrote:

    > How do you think dictionaries and arrays of things are handed back
    > to you from other Cocoa methods? A hint: the same way. :-) If you
    > weren't able to rely on the object being returned sticking around long
    > enough for you to at least retain it, nothing would work right.

    I'm in full agreement :) I knew they would stick around in the
    current method (where I could retain it if I needed to), but I was
    looking for verification that the object would still be around in the
    method that called the method that generated it.

    > I see some prefer the style (on a "getter" accessor method) of:
    >
    > return [[object retain] autorelease];
    >
    > But the memory management guide says simply returning the object is
    > sufficient: "... no need for retain or release:". Given that, I don't
    > think that really buys you anything in the general case.

    I like simplicity too!

    > FWIW, I use the "hand back a dictionary to return multiple values"
    > approach frequently. It's (IMHO) a natural use of such a "throw-away"
    > container.

    I'm glad you took the time to write this. I always find it a thrill
    when I think of a way to do something and it turns out to be OK.
  • On Sep 21, 2007, at 10:04 AM, Scott Ribe wrote:
    >> I see some prefer the style (on a "getter" accessor method) of:
    >>
    >> return [[object retain] autorelease];
    >
    > In an accessor method, that makes sense for objects that might be
    > shared
    > between threads. (And I can think of other situations, but they seem
    > pretty
    > contrived.) In the context of the current discussion it adds nothing,
    > because the retain/autorelease of the convenience method must have
    > been
    > performed in the current thread.

    Actually, -autorelease does not, in any way, add true thread safety to
    an accessor.  It only makes it more likely to work by delaying the
    reap of an object a little bit, thus allowing the other thread to -
    retain the object before it is reaped.

    If you want to "transfer ownership" of an object from one thread to
    another, you *must* retain in the giving thread and *must* either
    preserve that retain in the receiving thread OR retain in the
    receiving thread before releasing *or autoreleasing* in the giving
    thread.

    b.bum
  • > Actually, -autorelease does not, in any way, add true thread safety to
    > an accessor.  It only makes it more likely to work by delaying the
    > reap of an object a little bit, thus allowing the other thread to -
    > retain the object before it is reaped.

    Right; I've dealt with that before. I was thinking of the case in which the
    parent object is holding a retain on the member which it is returning. There
    still must be some synchronization somewhere to ensure that the parent
    object is not released from another thread, dealloc'd, and releases the
    object to be returned right in the middle of that accessor.

    > If you want to "transfer ownership" of an object from one thread to
    > another, you *must* retain in the giving thread and *must* either
    > preserve that retain in the receiving thread OR retain in the
    > receiving thread before releasing *or autoreleasing* in the giving
    > thread.

    Right; in this accessor the retain & autorelease are both in the "receiving
    thread", assuming multiple threads. So this pattern makes sure that the
    retain is put on in the receiving thread. Something else must ensure that no
    other thread releases in the middle of the accessor--that would often be
    implemented with synchronization on at least the dealloc and any such
    accessors, but there are other cases.

    Sorry to have given an incomplete discussion... Just wanted to point out
    that there can be good reasons retain/autorelease/return an object that is
    known to be retained.

    --
    Scott Ribe
    <scott_ribe...>
    http://www.killerbytes.com/
    (303) 722-0567 voice
  • On 9/21/07, Scott Ribe <scott_ribe...> wrote:
    >> I see some prefer the style (on a "getter" accessor method) of:
    >>
    >> return [[object retain] autorelease];
    >
    > In an accessor method, that makes sense for objects that might be shared
    > between threads.

    It makes the most sense for framework developers that want to help
    protect callers from side effects. For example an unrelated (from the
    prespective of the caller) setter could result in the object returned
    by the getter to be deallocated while still in the current stack frame
    (function/method). So using [[object retain] autorelease] will ensure
    that the vended object continues to exist in the callers autorelease
    pool and wont disappear when the caller uses some other aspect of the
    API.

    -Shawn
  • > Thanks. The reason for my question, though, was that I wasn't sure
    > _when_ that would happen.

    If you didn't create the autorelease pool yourself, most likely it
    will be released at the end of the current iteration of the event
    loop. As mentioned, there's no magic going on here, Cocoa simply
    creates an NSAutoreleasePool instance at the beginning of the event
    loop and releases it at the end. It's not possible for this pool to
    be released from under your feet.
previous month september 2007 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Go to today