Created
August 6, 2010 11:14
Revisions
-
nevyn revised this gist
Aug 28, 2010 . 3 changed files with 86 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,15 +1,21 @@ #import <Foundation/Foundation.h> @interface SPInvocationGrabber : NSObject { id _object; NSInvocation *_invocation; int frameCount; char **frameStrings; BOOL backgroundAfterForward; BOOL onMainAfterForward; BOOL waitUntilDone; } -(id)initWithObject:(id)obj; -(id)initWithObject:(id)obj stacktraceSaving:(BOOL)saveStack; @property (readonly, retain, nonatomic) id object; @property (readonly, retain, nonatomic) NSInvocation *invocation; @property BOOL backgroundAfterForward; @property BOOL onMainAfterForward; @property BOOL waitUntilDone; -(void)invoke; // will release object and invocation -(void)printBacktrace; -(void)saveBacktrace; @@ -19,4 +25,6 @@ -(id)grab; -(id)invokeAfter:(NSTimeInterval)delta; -(id)nextRunloop; -(id)inBackground; -(id)onMainAsync:(BOOL)async; @end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,6 +5,7 @@ @interface SPInvocationGrabber () @property (readwrite, retain, nonatomic) id object; @property (readwrite, retain, nonatomic) NSInvocation *invocation; @end @implementation SPInvocationGrabber @@ -31,10 +32,28 @@ -(void)dealloc; } @synthesize invocation = _invocation, object = _object; @synthesize backgroundAfterForward, onMainAfterForward, waitUntilDone; - (void)runInBackground; { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @try { [self invoke]; } @finally { [pool drain]; } } - (void)forwardInvocation:(NSInvocation *)anInvocation { [anInvocation retainArguments]; anInvocation.target = _object; self.invocation = anInvocation; if(backgroundAfterForward) [NSThread detachNewThreadSelector:@selector(runInBackground) toTarget:self withObject:nil]; else if(onMainAfterForward) [self performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:waitUntilDone]; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)inSelector { NSMethodSignature *signature = [super methodSignatureForSelector:inSelector]; @@ -45,7 +64,7 @@ - (NSMethodSignature *)methodSignatureForSelector:(SEL)inSelector { } - (void)invoke; { @try { [_invocation invoke]; @@ -87,7 +106,22 @@ -(id)invokeAfter:(NSTimeInterval)delta; [NSTimer scheduledTimerWithTimeInterval:delta target:grabber selector:@selector(invoke) userInfo:nil repeats:NO]; return grabber; } - (id)nextRunloop; { return [self invokeAfter:0]; } -(id)inBackground; { SPInvocationGrabber *grabber = [self grab]; grabber.backgroundAfterForward = YES; return grabber; } -(id)onMainAsync:(BOOL)async; { SPInvocationGrabber *grabber = [self grab]; grabber.onMainAfterForward = YES; grabber.waitUntilDone = !async; return grabber; } @end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,38 @@ #import <Cocoa/Cocoa.h> #import "NSObject+SPInvocationGrabbing.h" @interface Foo : NSObject { int a; } -(void)startIt; -(void)theBackgroundStuff; -(void)theForegroundStuff; @end @implementation Foo -(void)startIt; { NSLog(@"Starting out on the main thread..."); a = 3; [[self inBackground] theBackgroundStuff]; } -(void)theBackgroundStuff; { NSLog(@"Woah, this is a background thread!"); a += 6; [[self onMainAsync:YES] theForegroundStuff]; } -(void)theForegroundStuff; { NSLog(@"Hey presto: %d", a); } @end int main() { NSAutoreleasePool *pool = [NSAutoreleasePool new]; Foo *foo = [Foo new]; [foo startIt]; [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; [pool release]; return 0; } -
nevyn revised this gist
Aug 6, 2010 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,7 +6,7 @@ -(BOOL)areTheNewViewersGoneYet:(Duck*)duck; id invocationGrabber = [[[SPInvocationGrabber alloc] initWithTarget:myInstance] autorelease]; [invocationGrabber areTheNewViewersGoneYet:[Duck yellowDuck]]; // line 9 NSInvocation *invocationForAreTheNewViewersGoneYet = [invocationGrabber invocation]; -
nevyn revised this gist
Aug 6, 2010 . 1 changed file with 12 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,12 @@ @interface MyClass : NSObject -(BOOL)areTheNewViewersGoneYet:(Duck*)duck; @end ... MyClass *myInstance = [[MyClass alloc] init]; id invocationGrabber = [[[SPInvocationGrabber alloc] initWithTarget:myInstance] autorelease]; [invocationGrabber areTheNewViewersGoneYet:[Duck yellowDuck]]; NSInvocation *invocationForAreTheNewViewersGoneYet = [invocationGrabber invocation]; -
nevyn revised this gist
Aug 6, 2010 . 1 changed file with 28 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,28 @@ // A +(UIView*)flashAt:(CGRect)r in:(UIView*)parent color:(UIColor*)color; { float duration = 0.5; UIView *flash = [[[UIView alloc] initWithFrame:r] autorelease]; flash.backgroundColor = color; [parent addSubview:flash]; [[flash invokeAfter:duration+0.1] removeFromSuperview]; [UIView beginAnimations:@"SPFlash" context:NULL]; [UIView setAnimationDuration:duration]; flash.alpha = 0.0; [UIView commitAnimations]; return flash; } // B - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Force the animation to happen by calling this method again after a small // delay - see http://blog.instapaper.com/post/53568356 [[self nextRunloop] delayedTableViewDidSelectRowAtIndexPath: indexPath]; } // C [[tableView invokeAfter:0.15] selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone]; [[tableView invokeAfter:0.30] deselectRowAtIndexPath:indexPath animated:YES]; [[tableView invokeAfter:0.45] selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone]; -
nevyn revised this gist
Aug 6, 2010 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -83,7 +83,7 @@ -(id)grab; } -(id)invokeAfter:(NSTimeInterval)delta; { id grabber = [self grab]; [NSTimer scheduledTimerWithTimeInterval:delta target:grabber selector:@selector(invoke) userInfo:nil repeats:NO]; return grabber; } -
nevyn revised this gist
Aug 6, 2010 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ #import "NSObject+SPInvocationGrabbing.h" #import <execinfo.h> #pragma mark Invocation grabbing @@ -51,7 +51,7 @@ - (void)invoke; [_invocation invoke]; } @catch (NSException * e) { NSLog(@"SPInvocationGrabber's target raised %@:\n\t%@\nInvocation was originally scheduled at:", e.name, e); [self printBacktrace]; printf("\n"); [e raise]; -
nevyn created this gist
Aug 6, 2010 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,22 @@ #import <Foundation/Foundation.h> @interface SPInvocationGrabber : NSObject { id _object; NSInvocation *_invocation; int frameCount; char **frameStrings; } -(id)initWithObject:(id)obj; -(id)initWithObject:(id)obj stacktraceSaving:(BOOL)saveStack; @property (readonly, retain, nonatomic) id object; @property (readonly, retain, nonatomic) NSInvocation *invocation; -(void)invoke; // will release object and invocation -(void)printBacktrace; -(void)saveBacktrace; @end @interface NSObject (SPInvocationGrabbing) -(id)grab; -(id)invokeAfter:(NSTimeInterval)delta; -(id)nextRunloop; @end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,93 @@ #import "NSObject+Spotify.h" #import <execinfo.h> #pragma mark Invocation grabbing @interface SPInvocationGrabber () @property (readwrite, retain, nonatomic) id object; @property (readwrite, retain, nonatomic) NSInvocation *invocation; @end @implementation SPInvocationGrabber - (id)initWithObject:(id)obj; { return [self initWithObject:obj stacktraceSaving:YES]; } -(id)initWithObject:(id)obj stacktraceSaving:(BOOL)saveStack; { self.object = obj; if(saveStack) [self saveBacktrace]; return self; } -(void)dealloc; { free(frameStrings); self.object = nil; self.invocation = nil; [super dealloc]; } @synthesize invocation = _invocation, object = _object; - (void)forwardInvocation:(NSInvocation *)anInvocation { [anInvocation retainArguments]; anInvocation.target = _object; self.invocation = anInvocation; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)inSelector { NSMethodSignature *signature = [super methodSignatureForSelector:inSelector]; if (signature == NULL) signature = [_object methodSignatureForSelector:inSelector]; return signature; } - (void)invoke; { @try { [_invocation invoke]; } @catch (NSException * e) { SPNSLog(@"SPInvocationGrabber's target raised %@:\n\t%@\nInvocation was originally scheduled at:", e.name, e); [self printBacktrace]; printf("\n"); [e raise]; } self.invocation = nil; self.object = nil; } -(void)saveBacktrace; { void *backtraceFrames[128]; frameCount = backtrace(&backtraceFrames[0], 128); frameStrings = backtrace_symbols(&backtraceFrames[0], frameCount); } -(void)printBacktrace; { for(int x = 3; x < frameCount; x++) { if(frameStrings[x] == NULL) { break; } printf("%s\n", frameStrings[x]); } } @end @implementation NSObject (SPInvocationGrabbing) -(id)grab; { return [[[SPInvocationGrabber alloc] initWithObject:self] autorelease]; } -(id)invokeAfter:(NSTimeInterval)delta; { id grabber = [[[SPInvocationGrabber alloc] initWithObject:self] autorelease]; [NSTimer scheduledTimerWithTimeInterval:delta target:grabber selector:@selector(invoke) userInfo:nil repeats:NO]; return grabber; } - (id)nextRunloop { return [self invokeAfter:0]; } @end