+++ /dev/null
-@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