Call -[NSInvocation retainArguments] in ThreadSafeDelegate.
[macgdbp.git] / Source / ThreadSafeDeleage.m
1 /*
2 * MacGDBp
3 * Copyright (c) 2013, Blue Static <http://www.bluestatic.org>
4 *
5 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6 * General Public License as published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
10 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along with this program; if not,
14 * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17 #import "ThreadSafeDeleage.h"
18
19 @implementation ThreadSafeDeleage {
20 NSObject* _object;
21 Protocol* _protocol;
22 NSThread* _thread;
23 NSArray* _modes;
24 }
25
26 @synthesize object = _object;
27
28 - (id)initWithObject:(NSObject*)object
29 protocol:(Protocol*)protocol
30 thread:(NSThread*)thread {
31 return [self initWithObject:object
32 protocol:protocol
33 thread:thread
34 modes:@[ NSRunLoopCommonModes ]];
35 }
36
37 - (id)initWithObject:(NSObject*)object
38 protocol:(Protocol*)protocol
39 thread:(NSThread*)thread
40 modes:(NSArray*)runLoopModes {
41 if ((self = [super init])) {
42 _object = object;
43 _protocol = protocol;
44 _thread = thread;
45 _modes = [runLoopModes retain];
46 }
47 return self;
48 }
49
50 - (void)dealloc {
51 [_modes release];
52 [super dealloc];
53 }
54
55 - (BOOL)conformsToProtocol:(Protocol*)protocol {
56 return [_protocol isEqual:protocol];
57 }
58
59 - (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector {
60 if (!_object)
61 return [_protocol methodSignatureForSelector:aSelector];
62 return [_object methodSignatureForSelector:aSelector];
63 }
64
65 - (BOOL)respondsToSelector:(SEL)aSelector {
66 if (!_object)
67 return [_protocol respondsToSelector:aSelector];
68 return [_object respondsToSelector:aSelector];
69 }
70
71 - (void)forwardInvocation:(NSInvocation*)invocation {
72 if ([_object respondsToSelector:[invocation selector]]) {
73 [invocation retainArguments];
74 [self performSelector:@selector(dispatchInvocation:)
75 onThread:_thread
76 withObject:invocation
77 waitUntilDone:NO
78 modes:_modes];
79 }
80 }
81
82 - (void)dispatchInvocation:(NSInvocation*)invocation {
83 [invocation invokeWithTarget:_object];
84 }
85
86 @end