first commit
This commit is contained in:
64
UICaboodle/UCYield.h
Normal file
64
UICaboodle/UCYield.h
Normal file
@@ -0,0 +1,64 @@
|
||||
@interface NSObject (UICaboodle)
|
||||
- (id) yieldToSelector:(SEL)selector withObject:(id)object;
|
||||
- (id) yieldToSelector:(SEL)selector;
|
||||
@end
|
||||
|
||||
@implementation NSObject (UICaboodle)
|
||||
|
||||
- (void) doNothing {
|
||||
}
|
||||
|
||||
- (void) _yieldToContext:(NSMutableArray *)context { _pooled
|
||||
SEL selector(reinterpret_cast<SEL>([[context objectAtIndex:0] pointerValue]));
|
||||
id object([[context objectAtIndex:1] nonretainedObjectValue]);
|
||||
volatile bool &stopped(*reinterpret_cast<bool *>([[context objectAtIndex:2] pointerValue]));
|
||||
|
||||
/* XXX: deal with exceptions */
|
||||
id value([self performSelector:selector withObject:object]);
|
||||
|
||||
NSMethodSignature *signature([self methodSignatureForSelector:selector]);
|
||||
[context removeAllObjects];
|
||||
if ([signature methodReturnLength] != 0 && value != nil)
|
||||
[context addObject:value];
|
||||
|
||||
stopped = true;
|
||||
|
||||
[self
|
||||
performSelectorOnMainThread:@selector(doNothing)
|
||||
withObject:nil
|
||||
waitUntilDone:NO
|
||||
];
|
||||
}
|
||||
|
||||
- (id) yieldToSelector:(SEL)selector withObject:(id)object {
|
||||
/*return [self performSelector:selector withObject:object];*/
|
||||
|
||||
volatile bool stopped(false);
|
||||
|
||||
NSMutableArray *context([NSMutableArray arrayWithObjects:
|
||||
[NSValue valueWithPointer:selector],
|
||||
[NSValue valueWithNonretainedObject:object],
|
||||
[NSValue valueWithPointer:const_cast<bool *>(&stopped)],
|
||||
nil]);
|
||||
|
||||
NSThread *thread([[[NSThread alloc]
|
||||
initWithTarget:self
|
||||
selector:@selector(_yieldToContext:)
|
||||
object:context
|
||||
] autorelease]);
|
||||
|
||||
[thread start];
|
||||
|
||||
NSRunLoop *loop([NSRunLoop currentRunLoop]);
|
||||
NSDate *future([NSDate distantFuture]);
|
||||
|
||||
while (!stopped && [loop runMode:NSDefaultRunLoopMode beforeDate:future]);
|
||||
|
||||
return [context count] == 0 ? nil : [context objectAtIndex:0];
|
||||
}
|
||||
|
||||
- (id) yieldToSelector:(SEL)selector {
|
||||
return [self yieldToSelector:selector withObject:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user