blob: dc75f8f417bd55f3ae41ca25a13a74d60e460be7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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
|