jens@0: // jens@0: // Target.m jens@0: // MYUtilities jens@0: // jens@0: // Created by Jens Alfke on 2/11/08. jens@0: // Copyright 2008 Jens Alfke. All rights reserved. jens@0: // jens@0: jens@0: #import "Target.h" jens@0: jens@0: jens@7: @implementation MYTarget jens@7: jens@7: jens@7: - (id) initWithReceiver: (id)receiver action: (SEL)action jens@0: { jens@7: self = [super init]; jens@7: if( self ) { jens@7: NSMethodSignature *sig = [receiver methodSignatureForSelector: action]; jens@7: CAssert(sig,@"%@<%p> does not respond to %@",[receiver class],receiver,NSStringFromSelector(action)); jens@7: CAssert(sig.numberOfArguments==3, jens@7: @"-[%@ %@] can't be used as a target because it takes >1 param", jens@7: [receiver class],NSStringFromSelector(action)); jens@7: CAssert(0==strcmp([sig getArgumentTypeAtIndex: 2],"@"), jens@7: @"-[%@ %@] can't be used as a target because it takes a non-object param", jens@7: [receiver class],NSStringFromSelector(action)); jens@7: NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sig]; jens@7: inv.target = receiver; jens@7: inv.selector = action; jens@7: _invocations = [inv retain]; jens@7: } jens@7: return self; jens@0: } jens@0: jens@7: + (MYTarget*) targetWithReceiver: (id)receiver action: (SEL)action jens@7: { jens@7: return [[[self alloc] initWithReceiver: receiver action: action] autorelease]; jens@7: } jens@0: jens@7: - (void) dealloc jens@7: { jens@7: [_invocations release]; jens@7: [super dealloc]; jens@7: } jens@7: jens@7: jens@7: - (NSArray*) invocations jens@7: { jens@7: NSMutableArray *invocations = $castIf(NSMutableArray,_invocations); jens@7: if( ! invocations ) jens@7: invocations = [NSMutableArray arrayWithObject: _invocations]; jens@7: return invocations; jens@7: } jens@7: jens@7: jens@7: - (NSString*) description jens@7: { jens@7: NSMutableString *desc = [NSMutableString stringWithFormat: @"%@{", self.class]; jens@7: BOOL first = YES; jens@7: for( NSInvocation *inv in self.invocations ) { jens@7: if( first ) jens@7: first = NO; jens@7: else jens@7: [desc appendString: @", "]; jens@7: [desc appendFormat: @"-[%@ %s]", [inv.target class], inv.selector]; jens@7: } jens@7: [desc appendString: @"}"]; jens@7: return desc; jens@7: } jens@7: jens@7: jens@7: static BOOL equalInvocations( NSInvocation *a, NSInvocation *b ) jens@7: { jens@7: return a.target==b.target && a.selector==b.selector; jens@7: } jens@7: jens@7: jens@7: - (BOOL) isEqual: (MYTarget*)t jens@7: { jens@7: if( ! [t isKindOfClass: [self class]] ) jens@7: return NO; jens@7: if( [_invocations isKindOfClass: [NSInvocation class]] && [t->_invocations isKindOfClass: [NSInvocation class]] ) jens@7: return equalInvocations(_invocations,t->_invocations); jens@7: NSArray *myInvocations = self.invocations, *itsInvocations = t.invocations; jens@7: unsigned n = myInvocations.count; jens@7: if( n != itsInvocations.count ) jens@7: return NO; jens@7: for( int i=0; i