mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
Fixed NSUndoManager bug #14448 by extending NSInvocation with the possibility to retain or not the target
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@21721 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
2bbc7e41a6
commit
3df62a4799
4 changed files with 79 additions and 32 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2005-09-17 Saso Kiselkov <diablos@manga.sk>
|
||||
|
||||
* Headers/Foundation/NSInvocation.h:
|
||||
* Source/NSInvocation.m:
|
||||
(-targetRetained, -retainArgumentsIncludingTarget:):
|
||||
Added new methods which allow target to be not retained when arguments
|
||||
are and to check whether it is retained or not (-retainsArguments code
|
||||
moved in -retainArgumentsIncludingTarged and simplified by removing a
|
||||
redundant nested branch statement).
|
||||
* Source/NSUndoManager.m (-forwardInvocation:,
|
||||
-registerUndoWithTarget:selector:object:): Fixed bug #14488 by relying
|
||||
on previous new methods to retain undo invocation (taking in account
|
||||
the fact arguments may have been released before it is called).
|
||||
Patch committed by Quentin Mathe.
|
||||
|
||||
2005-09-01 Adam Fedor <fedor@gnu.org>
|
||||
|
||||
* Source/NSSortDescriptor.m ([NSArray
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
void *_dummy;
|
||||
#endif
|
||||
BOOL _argsRetained;
|
||||
BOOL _targetRetained;
|
||||
BOOL _validReturn;
|
||||
BOOL _sendToSuper;
|
||||
}
|
||||
|
@ -71,6 +72,11 @@
|
|||
- (BOOL) argumentsRetained;
|
||||
- (void) retainArguments;
|
||||
|
||||
#if OS_API_VERSION(GS_API_NONE,GS_API_NONE) && GS_API_VERSION(011201,GS_API_LATEST)
|
||||
- (BOOL) targetRetained;
|
||||
- (void) retainArgumentsIncludingTarget: (BOOL)retainTargetFlag;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dispatching an Invocation.
|
||||
*/
|
||||
|
|
|
@ -189,9 +189,13 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (_targetRetained)
|
||||
{
|
||||
_targetRetained = NO;
|
||||
RELEASE(_target);
|
||||
}
|
||||
if (_argsRetained)
|
||||
{
|
||||
RELEASE(_target);
|
||||
_argsRetained = NO;
|
||||
if (_cframe && _sig)
|
||||
{
|
||||
|
@ -437,11 +441,14 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
*/
|
||||
- (void) setTarget: (id)anObject
|
||||
{
|
||||
if (_argsRetained)
|
||||
if (_targetRetained)
|
||||
{
|
||||
ASSIGN(_target, anObject);
|
||||
}
|
||||
_target = anObject;
|
||||
else
|
||||
{
|
||||
_target = anObject;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -463,55 +470,73 @@ _arg_addr(NSInvocation *inv, int index)
|
|||
|
||||
/**
|
||||
* Instructs the invocation to retain its object arguments (including the
|
||||
* target). The default is not to retain them.
|
||||
* target). The default is not to retain them.
|
||||
*/
|
||||
- (void) retainArguments
|
||||
{
|
||||
if (_argsRetained)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
[self retainArgumentsIncludingTarget: YES];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns YES if target has been retained yet, NO otherwise.
|
||||
*/
|
||||
- (BOOL) targetRetained
|
||||
{
|
||||
return _targetRetained;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to -[NSInvocation retainArguments], but allows the sender to
|
||||
* explicitly control whether the target is retained as well. Retaining
|
||||
* the target is sometimes not desirable (such as in NSUndoManager), as
|
||||
* retain loops could result.
|
||||
*/
|
||||
- (void) retainArgumentsIncludingTarget: (BOOL)retainTargetFlag
|
||||
{
|
||||
if (_argsRetained == NO)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
_argsRetained = YES;
|
||||
IF_NO_GC(RETAIN(_target));
|
||||
if (_cframe == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (i = 3; i <= _numArgs; i++)
|
||||
{
|
||||
if (*_info[i].type == _C_ID || *_info[i].type == _C_CHARPTR)
|
||||
if (*_info[i].type == _C_ID)
|
||||
{
|
||||
if (*_info[i].type == _C_ID)
|
||||
{
|
||||
id old;
|
||||
id old;
|
||||
|
||||
_get_arg(self, i-1, &old);
|
||||
if (old != nil)
|
||||
{
|
||||
IF_NO_GC(RETAIN(old));
|
||||
}
|
||||
_get_arg(self, i-1, &old);
|
||||
if (old != nil)
|
||||
{
|
||||
IF_NO_GC(RETAIN(old));
|
||||
}
|
||||
else
|
||||
{
|
||||
char *str;
|
||||
}
|
||||
else if (*_info[i].type == _C_CHARPTR)
|
||||
{
|
||||
char *str;
|
||||
|
||||
_get_arg(self, i-1, &str);
|
||||
if (str != 0)
|
||||
{
|
||||
char *tmp;
|
||||
_get_arg(self, i-1, &str);
|
||||
if (str != 0)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
tmp = NSZoneMalloc(NSDefaultMallocZone(), strlen(str)+1);
|
||||
strcpy(tmp, str);
|
||||
_set_arg(self, i-1, &tmp);
|
||||
}
|
||||
tmp = NSZoneMalloc(NSDefaultMallocZone(), strlen(str)+1);
|
||||
strcpy(tmp, str);
|
||||
_set_arg(self, i-1, &tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (retainTargetFlag && _targetRetained == NO)
|
||||
{
|
||||
_targetRetained = YES;
|
||||
|
||||
IF_NO_GC(RETAIN(_target));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -425,6 +425,7 @@
|
|||
format: @"forwardInvocation without beginUndoGrouping"];
|
||||
}
|
||||
}
|
||||
[anInvocation retainArgumentsIncludingTarget: NO];
|
||||
[anInvocation setTarget: _nextTarget];
|
||||
_nextTarget = nil;
|
||||
[_group addInvocation: anInvocation];
|
||||
|
@ -726,7 +727,7 @@
|
|||
g = _group;
|
||||
sig = [target methodSignatureForSelector: aSelector];
|
||||
inv = [NSInvocation invocationWithMethodSignature: sig];
|
||||
[inv retainArguments];
|
||||
[inv retainArgumentsIncludingTarget: NO];
|
||||
[inv setTarget: target];
|
||||
[inv setSelector: aSelector];
|
||||
[inv setArgument: &anObject atIndex: 2];
|
||||
|
|
Loading…
Reference in a new issue