mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-25 01:31:08 +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
a27efb2586
commit
1c3d59ee22
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>
|
2005-09-01 Adam Fedor <fedor@gnu.org>
|
||||||
|
|
||||||
* Source/NSSortDescriptor.m ([NSArray
|
* Source/NSSortDescriptor.m ([NSArray
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
void *_dummy;
|
void *_dummy;
|
||||||
#endif
|
#endif
|
||||||
BOOL _argsRetained;
|
BOOL _argsRetained;
|
||||||
|
BOOL _targetRetained;
|
||||||
BOOL _validReturn;
|
BOOL _validReturn;
|
||||||
BOOL _sendToSuper;
|
BOOL _sendToSuper;
|
||||||
}
|
}
|
||||||
|
@ -71,6 +72,11 @@
|
||||||
- (BOOL) argumentsRetained;
|
- (BOOL) argumentsRetained;
|
||||||
- (void) retainArguments;
|
- (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.
|
* Dispatching an Invocation.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -189,9 +189,13 @@ _arg_addr(NSInvocation *inv, int index)
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
|
if (_targetRetained)
|
||||||
|
{
|
||||||
|
_targetRetained = NO;
|
||||||
|
RELEASE(_target);
|
||||||
|
}
|
||||||
if (_argsRetained)
|
if (_argsRetained)
|
||||||
{
|
{
|
||||||
RELEASE(_target);
|
|
||||||
_argsRetained = NO;
|
_argsRetained = NO;
|
||||||
if (_cframe && _sig)
|
if (_cframe && _sig)
|
||||||
{
|
{
|
||||||
|
@ -437,11 +441,14 @@ _arg_addr(NSInvocation *inv, int index)
|
||||||
*/
|
*/
|
||||||
- (void) setTarget: (id)anObject
|
- (void) setTarget: (id)anObject
|
||||||
{
|
{
|
||||||
if (_argsRetained)
|
if (_targetRetained)
|
||||||
{
|
{
|
||||||
ASSIGN(_target, anObject);
|
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
|
* 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
|
- (void) retainArguments
|
||||||
{
|
{
|
||||||
if (_argsRetained)
|
[self retainArgumentsIncludingTarget: YES];
|
||||||
{
|
}
|
||||||
return;
|
|
||||||
}
|
/**
|
||||||
else
|
* 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;
|
unsigned int i;
|
||||||
|
|
||||||
_argsRetained = YES;
|
_argsRetained = YES;
|
||||||
IF_NO_GC(RETAIN(_target));
|
|
||||||
if (_cframe == 0)
|
if (_cframe == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (i = 3; i <= _numArgs; i++)
|
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);
|
_get_arg(self, i-1, &old);
|
||||||
if (old != nil)
|
if (old != nil)
|
||||||
{
|
{
|
||||||
IF_NO_GC(RETAIN(old));
|
IF_NO_GC(RETAIN(old));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
else if (*_info[i].type == _C_CHARPTR)
|
||||||
char *str;
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
_get_arg(self, i-1, &str);
|
_get_arg(self, i-1, &str);
|
||||||
if (str != 0)
|
if (str != 0)
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
tmp = NSZoneMalloc(NSDefaultMallocZone(), strlen(str)+1);
|
tmp = NSZoneMalloc(NSDefaultMallocZone(), strlen(str)+1);
|
||||||
strcpy(tmp, str);
|
strcpy(tmp, str);
|
||||||
_set_arg(self, i-1, &tmp);
|
_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"];
|
format: @"forwardInvocation without beginUndoGrouping"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[anInvocation retainArgumentsIncludingTarget: NO];
|
||||||
[anInvocation setTarget: _nextTarget];
|
[anInvocation setTarget: _nextTarget];
|
||||||
_nextTarget = nil;
|
_nextTarget = nil;
|
||||||
[_group addInvocation: anInvocation];
|
[_group addInvocation: anInvocation];
|
||||||
|
@ -726,7 +727,7 @@
|
||||||
g = _group;
|
g = _group;
|
||||||
sig = [target methodSignatureForSelector: aSelector];
|
sig = [target methodSignatureForSelector: aSelector];
|
||||||
inv = [NSInvocation invocationWithMethodSignature: sig];
|
inv = [NSInvocation invocationWithMethodSignature: sig];
|
||||||
[inv retainArguments];
|
[inv retainArgumentsIncludingTarget: NO];
|
||||||
[inv setTarget: target];
|
[inv setTarget: target];
|
||||||
[inv setSelector: aSelector];
|
[inv setSelector: aSelector];
|
||||||
[inv setArgument: &anObject atIndex: 2];
|
[inv setArgument: &anObject atIndex: 2];
|
||||||
|
|
Loading…
Reference in a new issue