65 lines
1.8 KiB
Objective-C
65 lines
1.8 KiB
Objective-C
@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
|