-
Notifications
You must be signed in to change notification settings - Fork 3
/
PubSub.m
86 lines (63 loc) · 2.17 KB
/
PubSub.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
//
// PubSub.m
//
// Josh Wright
// http://bendytree.com
// @BendyTree
// June 4, 2013
//
// Use this however you want.
//
#import "PubSub.h"
#import <objc/runtime.h>
#import <objc/Protocol.h>
#import <Foundation/Foundation.h>
@implementation Sub
+ (id) mockSubscribeWhile:(id)keepAlive callback:(void(^)(id arg))callback { return nil; }
+ (NSMethodSignature *) methodSignatureForSelector:(SEL)selector
{
NSMethodSignature* signature = [super methodSignatureForSelector:selector];
if (!signature) {
signature = [self methodSignatureForSelector:@selector(mockSubscribeWhile:callback:)];
}
return signature;
return nil;
}
+ (void) forwardInvocation:(NSInvocation *)anInvocation
{
SEL aSelector = [anInvocation selector];
__unsafe_unretained id keepAlive = nil;
[anInvocation getArgument:&keepAlive atIndex:2];
void(^callback)(id arg) = nil;
[anInvocation getArgument:&callback atIndex:3];
NSString* notificationName = [NSStringFromSelector(aSelector) componentsSeparatedByString:@":"][1];
__weak id keepAliveWeakRef = keepAlive;
__block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:notificationName object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification* notification){
id keepAliveStrong = keepAliveWeakRef;
if(keepAliveStrong == nil){
[[NSNotificationCenter defaultCenter] removeObserver:observer];
return;
}
callback(notification.object);
}];
}
@end
@implementation Pub
+ (void) mockPublish:(id)arg { }
+ (NSMethodSignature *) methodSignatureForSelector:(SEL)selector
{
NSMethodSignature* signature = [super methodSignatureForSelector:selector];
if (!signature)
{
signature = [self methodSignatureForSelector:@selector(mockPublish:)];
}
return signature;
}
+ (void)forwardInvocation:(NSInvocation *)i
{
id arg = nil;
[i getArgument:&arg atIndex:2];
NSString* notificationName = [NSStringFromSelector(i.selector) componentsSeparatedByString:@":"][0];
[[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:arg];
}
@end