forked from iMediaSandboxing/iMedia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
UKMainThreadProxy.m
152 lines (114 loc) · 3.96 KB
/
UKMainThreadProxy.m
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* =============================================================================
FILE: UKMainThreadProxy.h
PROJECT: UKMainThreadProxy
PURPOSE: Send a message to object theObject to [theObject mainThreadProxy]
instead and the message will be received on the main thread by
theObject.
COPYRIGHT: (c) 2004 M. Uli Kusterer, all rights reserved.
AUTHORS: M. Uli Kusterer - UK
LICENSES: MIT License
REVISIONS:
2006-03-13 UK Clarified license.
2004-10-14 UK Created.
========================================================================== */
// -----------------------------------------------------------------------------
// Headers:
// -----------------------------------------------------------------------------
#import "UKMainThreadProxy.h"
@implementation UKMainThreadProxy
-(id) initWithTarget: (id)targ
{
self = [super init];
if( self )
{
target = targ;
waitForCompletion = YES;
}
return self;
}
-(void) setWaitForCompletion: (BOOL)state
{
waitForCompletion = state;
}
// -----------------------------------------------------------------------------
// Introspection overrides:
// -----------------------------------------------------------------------------
-(BOOL) respondsToSelector: (SEL)itemAction
{
BOOL does = [super respondsToSelector: itemAction];
return( does || [target respondsToSelector: itemAction] );
}
-(id) performSelector: (SEL)itemAction
{
BOOL does = [super respondsToSelector: itemAction];
if( does )
return [super performSelector: itemAction];
if( ![target respondsToSelector: itemAction] )
[self doesNotRecognizeSelector: itemAction];
[target retain];
[target performSelectorOnMainThread: itemAction withObject: nil waitUntilDone: waitForCompletion];
[target release];
return nil;
}
-(id) performSelector: (SEL)itemAction withObject: (id)obj
{
BOOL does = [super respondsToSelector: itemAction];
if( does )
return [super performSelector: itemAction withObject: obj];
if( ![target respondsToSelector: itemAction] )
[self doesNotRecognizeSelector: itemAction];
[target retain];
[obj retain];
[target performSelectorOnMainThread: itemAction withObject: obj waitUntilDone: waitForCompletion];
[obj release];
[target release];
return nil;
}
// -----------------------------------------------------------------------------
// Forwarding unknown methods to the target:
// -----------------------------------------------------------------------------
-(NSMethodSignature*) methodSignatureForSelector: (SEL)itemAction
{
NSMethodSignature* sig = [super methodSignatureForSelector: itemAction];
if( sig )
return sig;
return [target methodSignatureForSelector: itemAction];
}
-(void) forwardInvocation: (NSInvocation*)invocation
{
SEL itemAction = [invocation selector];
if( [target respondsToSelector: itemAction] )
{
[invocation retainArguments];
[target retain];
[invocation performSelectorOnMainThread: @selector(invokeWithTarget:) withObject: target waitUntilDone: waitForCompletion];
[target release];
}
else
[self doesNotRecognizeSelector: itemAction];
}
// -----------------------------------------------------------------------------
// Safety net:
// -----------------------------------------------------------------------------
-(id) mainThreadProxy // Just in case someone accidentally sends this message to a main thread proxy.
{
return self;
}
-(id) copyMainThreadProxy // Just in case someone accidentally sends this message to a main thread proxy.
{
return [self retain];
}
@end
// -----------------------------------------------------------------------------
// Shorthand notation for getting a main thread proxy:
// -----------------------------------------------------------------------------
@implementation NSObject (UKMainThreadProxy)
-(id) mainThreadProxy
{
return [[[UKMainThreadProxy alloc] initWithTarget: self] autorelease];
}
-(id) copyMainThreadProxy
{
return [[UKMainThreadProxy alloc] initWithTarget: self];
}
@end