• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NSUndoManager retain/release of arguments - ad infinitum
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSUndoManager retain/release of arguments - ad infinitum


  • Subject: Re: NSUndoManager retain/release of arguments - ad infinitum
  • From: John Bartleson <email@hidden>
  • Date: Thu, 13 Jan 2011 00:52:56 -0800

Thank you all for your comments. Because I think this is an important topic (and because I'm stubborn)
I'm going to continue to beat it to death.


Because there were a number of issues brought up in the comments, let me summarize them, with my
responses in line:


** Comment 1 (Graham Cox, January 10, 2011 9:39:06 PM PST) **
"My first thought, before I go further, is that to undo a sort, you are doing things way too
complicated. You only need to pass the sort descriptors to the undo manager, not a copy of the data."
** Response to Comment 1 **
It appears that I didn't properly explain that the code I included in my second post is only
executed if the dataSource method determines that no old sortDescriptors exist for the
data array, meaning the array is initially unsorted. If both old and new sort descriptors
exist for the data array, which means that the array has been previously sorted, my main
tableView:sortDescriptorsDidChange: method sets up an undo with swapped old and new descriptors
and then sorts using the new descriptors. Simple, like you said. I didn't include this main method
in my post. I call the code in Part 1 and Part 2 of my post only if, as Jerry Krinock pointed out
(January 10, 2011 10:35:28 PM PST), "...the objects had been manually arranged into some arbitrary
order by the user" and there are no old sort descriptors to use for undo. In this case, it seemed
to me that the most efficient way to recover the original arbitrary data order was to make a
shallow copy of the entire array.
** Comment 2 (Steven Hooley, January 11, 2011 3:27:47 AM PST) **
"either : a) sort order is a property of the window, not your model and shouldn't be undoable at
all.... OR b) the sort order is inherently part of your model, your data is an ordered-set and the
user can arbitrarily order the items as she pleases."
** Response to Comment 2 **
Good point, and one that I hadn't thought of. I had simplistically designed my app to use
sort order as b) part of the model, but a) suggests interesting design possibilities.
** Comment 3 (Graham Cox, January 10, 2011 9:39:06 PM PST) **
"Specifying 'assign' here is probably wrong. It is not retaining the assigned array, so you are
stating you don't own it. Yet I suspect that you do want to own it. You're relying on the undo
manager retaining it because you have neglected to do so."
** Response to Comment 3 **
You're right - it's sloppy coding on my part. In my post I showed the @property in a comment in case
someone would see if this was wrong. I changed the @property from 'assign' to 'retain', as you
suggested, and there's no crash on Redo. However, there's still a problem in that I don't know
if the array I allocated (in Part 1) with mutableCopyWithZone: is always being released. I'll
explain again:


The real point of my original plaintive cry, and I'm sorry if it's become obfuscated, is that I
had to allocate memory as part of setting up for undo, but I couldn't find any *simple* way to
keep track of whether that memory is still in use or not, thus threatening a memory leak. This
is not a sorting problem - it appears that it will occur generically whenever we write reference-
counted code that allocates memory and then passes that memory, usually via -prepareWithInvocationTarget:,
to an undo method.


Graham Cox made an interesting comment earlier:
"...once the undo manager performs the undo, it will release the invocation that is retaining
the array, which will dealloc it."


This gave me a glimmer of hope to explain what's going on. If in my method I allocate an
object (see the Part 1 code in my 2nd post), save a pointer to the object in the local variable
'unsortedArray', pass the pointer to -prepareWithInvocationTarget:, then exit the method, my pointer
is gone. If I haven't kept a copy of the pointer (say in an NSDocument instance variable)
-prepareWithInvocationTarget: (or the instance of NSUndoManager or whatever) is now sole
owner of the pointer.


Because it owns the only pointer, -prepareWithInvocationTarget: (or whatever) now owns the object.

Recall that, after I fixed my @property, my code appears to work properly. Ignoring the fact that
I don't know any way to verify that the object is actually being deallocated at NSDocument dealloc time,
I conclude that NSUndoManager and -prepareWithInvocationTarget: must be designed to retain and
release objects passed to them as needed to provide undo functionality. As Graham says: "it
follows the rules for ownership of objects, so by and large does the 'right thing'."


There's appears to be only one problem remaining: this behavior is not documented anywhere I can
find. In fact, Apple's 'Undo Architecture' implies just the opposite: "An NSUndoManager object does
not retain the targets of undo operations."
_______________________________________________


Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: NSUndoManager retain/release of arguments - ad infinitum
      • From: Graham Cox <email@hidden>
References: 
 >Re: NSUndoManager retain/release of arguments - ad infinitum (From: steven Hooley <email@hidden>)
 >Re: NSUndoManager retain/release of arguments - ad infinitum (From: Graham Cox <email@hidden>)

  • Prev by Date: NSView/NSResponder returns YES
  • Next by Date: Re: NSUndoManager retain/release of arguments - ad infinitum
  • Previous by thread: Re: NSUndoManager retain/release of arguments - ad infinitum
  • Next by thread: Re: NSUndoManager retain/release of arguments - ad infinitum
  • Index(es):
    • Date
    • Thread