Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ARC compatibility #9

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions GCUndoManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// 2010/01/01 - fixes for Core Data, optional retaining of targets, and prevention of reentrancy when removing tasks
// 2011/01/11 - fix to ensure submitting tasks in response to a checkpoint notification is correctly handled
// 2011/07/08 - added NSUndoManagerDidCloseUndoGroupNotification for 10.7 (Lion) compatibility
// 2013/10/14 - implemented ARC compatibility

#import <Foundation/Foundation.h>

Expand Down Expand Up @@ -272,8 +273,8 @@ GCUndoTaskCoalescingKind;
{
@private
NSInvocation* mInvocation;
id mTarget;
BOOL mTargetRetained;
__weak id mWeakTarget;
__strong id mStrongTarget;
}

- (id) initWithInvocation:(NSInvocation*) inv;
Expand Down
94 changes: 54 additions & 40 deletions GCUndoManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#import "GCUndoManager.h"

#import "JXArcCompatibilityMacros.h"

// this proxy object is returned by -prepareWithInvocationTarget: if GCUM_USE_PROXY is 1. This provides a similar behaviour to NSUndoManager
// on 10.6 so that a wider range of methods can be submitted as undo tasks. Unlike 10.6 however, it does not bypass um's -forwardInvocation:
// method, so subclasses still work when -forwardInvocaton: is overridden.
Expand Down Expand Up @@ -74,7 +76,7 @@ - (void) beginUndoGrouping
}

mOpenGroupRef = newGroup;
[newGroup release];
JX_RELEASE(newGroup);

if(![self isUndoing] && mGroupLevel > 0 )
[self checkpoint];
Expand Down Expand Up @@ -367,8 +369,8 @@ - (NSArray*) runLoopModes

- (void) setRunLoopModes:(NSArray*) modes
{
[modes retain];
[mRunLoopModes release];
JX_RETAIN(modes);
JX_RELEASE(mRunLoopModes);
mRunLoopModes = modes;

// n.b. if this is changed while a callback is pending, the new modes won't take effect until
Expand Down Expand Up @@ -491,7 +493,7 @@ - (void) forwardInvocation:(NSInvocation*) invocation
{
THROW_IF_FALSE( invocation != nil, @"-forwardInvocation: was passed an invalid nil invocation" );

GCConcreteUndoTask* task = [[[GCConcreteUndoTask alloc] initWithInvocation:invocation] autorelease];
GCConcreteUndoTask* task = JX_AUTORELEASE([[GCConcreteUndoTask alloc] initWithInvocation:invocation]);
[task setTarget:mNextTarget retained:[self retainsTargets]];
[self submitUndoTask:task];
}
Expand All @@ -510,7 +512,7 @@ - (void) registerUndoWithTarget:(id) target selector:(SEL) selector object:(i
{
THROW_IF_FALSE( selector != NULL, @"invalid (NULL) selector passed to registerUndoWithTarget:selector:object:" );

GCConcreteUndoTask* task = [[[GCConcreteUndoTask alloc] initWithTarget:target selector:selector object:anObject] autorelease];
GCConcreteUndoTask* task = JX_AUTORELEASE([[GCConcreteUndoTask alloc] initWithTarget:target selector:selector object:anObject]);
[task setTarget:target retained:[self retainsTargets]];
[self submitUndoTask:task];
}
Expand Down Expand Up @@ -563,7 +565,7 @@ - (void) removeAllActionsWithTarget:(id) target
}
}

[temp release];
JX_RELEASE(temp);

temp = [[self redoStack] copy];
iter = [temp objectEnumerator];
Expand All @@ -580,7 +582,7 @@ - (void) removeAllActionsWithTarget:(id) target
}
}

[temp release];
JX_RELEASE(temp);

mIsRemovingTargets = NO;
}
Expand Down Expand Up @@ -949,7 +951,7 @@ - (GCUndoGroup*) popUndo

if([mUndoStack count] > 0 )
{
GCUndoGroup* group = [[[self peekUndo] retain] autorelease];
GCUndoGroup* group = JX_RETAIN(JX_AUTORELEASE([self peekUndo]));
[mUndoStack removeLastObject];

return group;
Expand All @@ -965,7 +967,7 @@ - (GCUndoGroup*) popRedo

if([mRedoStack count] > 0 )
{
GCUndoGroup* group = [[[self peekRedo] retain] autorelease];
GCUndoGroup* group = JX_RETAIN(JX_AUTORELEASE([self peekRedo]));
[mRedoStack removeLastObject];

return group;
Expand Down Expand Up @@ -1063,7 +1065,7 @@ - (void) explodeTopUndoAction

[newTaskGroup setActionName:[NSString stringWithFormat:@"%@ (%lu: %@)", [topGroup actionName], (unsigned long)++suffix, selString ]];
[self pushGroupOntoUndoStack:newTaskGroup];
[newTaskGroup release];
JX_RELEASE(newTaskGroup);
}
}
}
Expand All @@ -1080,7 +1082,7 @@ - (id) init
mRedoStack = [[NSMutableArray alloc] init];

mGroupsByEvent = YES;
mRunLoopModes = [[NSArray arrayWithObject:NSDefaultRunLoopMode] retain];
mRunLoopModes = JX_RETAIN([NSArray arrayWithObject:NSDefaultRunLoopMode]);
mAutoDeleteEmptyGroups = YES;
mCoalKind = kGCCoalesceLastTask;

Expand All @@ -1098,11 +1100,13 @@ - (void) dealloc
{
[[NSRunLoop mainRunLoop] cancelPerformSelectorsWithTarget:self];

[mUndoStack release];
[mRedoStack release];
[mRunLoopModes release];
[mProxy release];
#if (JX_HAS_ARC == 0)
JX_RELEASE(mUndoStack);
JX_RELEASE(mRedoStack);
JX_RELEASE(mRunLoopModes);
JX_RELEASE(mProxy);
[super dealloc];
#endif
}


Expand Down Expand Up @@ -1284,7 +1288,7 @@ - (void) removeTasksWithTarget:(id) aTarget undoManager:(GCUndoManager*) um
}
}

[temp release];
JX_RELEASE(temp);
}


Expand All @@ -1293,8 +1297,8 @@ - (void) setActionName:(NSString*) name
{
// sets the group's action name. In general this is automatically handled by the owning undo manager

[name retain];
[mActionName release];
JX_RETAIN(name);
JX_RELEASE(mActionName);
mActionName = name;
}

Expand Down Expand Up @@ -1352,14 +1356,16 @@ - (id) init



#if (JX_HAS_ARC == 0)
- (void) dealloc
{
//NSLog(@"deallocating undo group %@", self );

[mTasks release];
[mActionName release];
JX_RELEASE(mTasks);
JX_RELEASE(mActionName);
[super dealloc];
}
#endif


- (NSString*) description
Expand Down Expand Up @@ -1387,14 +1393,14 @@ - (id) initWithInvocation:(NSInvocation*) inv
// the invocation retains its arguments and target if the target is set at this point. Therefore the target
// is set as nil and is managed independently. mTarget is set to the invocation's original target if set.

mTarget = [inv target];
mWeakTarget = [inv target];
[inv setTarget:nil];
[inv retainArguments];
mInvocation = [inv retain];
mInvocation = JX_RETAIN(inv);
}
else
{
[self autorelease];
JX_AUTORELEASE(self);
self = nil;
}
}
Expand All @@ -1414,18 +1420,24 @@ - (id) initWithTarget:(id) target selector:(SEL) selector object:(id) object

[inv setSelector:selector];

#if JX_HAS_ARC
__unsafe_unretained
#endif
id tempObject = object;

// don't set the argument if the selector doesn't take one

if([sig numberOfArguments] >= 3 )
[inv setArgument:&object atIndex:2];
if([sig numberOfArguments] >= 3 ) {
[inv setArgument:&tempObject atIndex:2];
}

self = [self initWithInvocation:inv];

// keep track of the target separately from the invocation, so it can be memory managed independently.
// The invocation's internal target is nil. The target is not retained unless -setTarget:retained: is called with YES for <retained>.

if( self )
mTarget = target;
mWeakTarget = target;

return self;
}
Expand All @@ -1435,20 +1447,22 @@ - (void) setTarget:(id) target retained:(BOOL) retainIt
{
// sets the invocation's target, optionally retaining it.

if( retainIt )
[target retain];
JX_RELEASE(mStrongTarget);

if( mTargetRetained )
[mTarget release];
if( retainIt ) {
mStrongTarget = JX_RETAIN(target);
}
else {
mStrongTarget = nil;
}

mTarget = target;
mTargetRetained = retainIt;
mWeakTarget = target;
}


- (id) target
{
return mTarget;
return mWeakTarget;
}


Expand All @@ -1467,8 +1481,8 @@ - (void) perform

//NSLog(@"about to invoke task %@", self );

if( mTarget )
[mInvocation invokeWithTarget:mTarget];
if( mWeakTarget )
[mInvocation invokeWithTarget:mWeakTarget];
}


Expand All @@ -1478,22 +1492,22 @@ - (void) perform

- (id) init
{
[self autorelease];
JX_AUTORELEASE(self);
return nil;
}



#if (JX_HAS_ARC == 0)
- (void) dealloc
{
[mInvocation release];
JX_RELEASE(mInvocation);

if( mTargetRetained )
[mTarget release];
JX_RELEASE(mStrongTarget);

[super dealloc];
}

#endif

- (NSString*) description
{
Expand Down
Loading