help-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

NSUndoManager and NSInvocation retain loops


From: Sašo Kiselkov
Subject: NSUndoManager and NSInvocation retain loops
Date: Sun, 11 Sep 2005 18:49:51 +0200
User-agent: Internet Messaging Program (IMP) 3.2.5

Hi.

I've encountered the following problem when using an NSUndoManager to handle
undo in my app:

When using invocation-based undo, the default GNUstep implementation of the undo
manager doesn't tell the invocation to retain it's arguments which will
obviously cause the app to crash in cases such as this:

@implementation MyDocument
- (void) setNameOfModelObjectTo: (NSString *) newName
{
  NSString * oldName = [aModelObject name];
  [[undoManager prepareWithInvocationTarget: self]
    setNameOfModelObjectTo: oldName];
  [aModelObject setName: newName];
}
@end

here when the user does 'Undo', the undo manager will invoke the
-setNameOfModelObjectTo: method again with the, presumably, old name (as was
set previously), but due to the fact that the -setName: method replaces the old
name with a new one and that the old name is not retained by the invocation, the
old name might get deallocated and the app will crash when it access the
`newName' argument during Undo. This can easily be solved by doing
-retainArguments in -[NSUndoManager forwardInvocation:] (I've already submitted
this as a bug report).

However, this introduces another problem: since invocations retain, when
-retainArguments is invoked, also their target, this will result in a retain
loop, where the original object which set up the undo-operation will be
referenced from inside the operation.

My question is: is it possible for NeXT to have missed this important fact when
designing OpenStep, or am I just doing something terribly wrong here? Is it a
bug? Does NSUndoManager need to be tuned to handle the special target retaining
rules? (NB. The same problem exists with NSTimer as well - an object which owns
a timer cannot set it up to invoke it's own methods, since the timer's
invocation will retain it's target and again a retain loop results - I've been
circumventing this by creating a proxy, but that's a dirty work-around.)

--
Saso





reply via email to

[Prev in Thread] Current Thread [Next in Thread]