-
Notifications
You must be signed in to change notification settings - Fork 7
/
CTBlockDescription.m
74 lines (60 loc) · 2.2 KB
/
CTBlockDescription.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
//
// CTBlockDescription.m
// CTBlockDescription
//
// Created by Oliver Letterer on 01.09.12.
// Copyright (c) 2012 olettere. All rights reserved.
//
#import "CTBlockDescription.h"
@implementation CTBlockDescription
- (id)initWithBlock:(id)block
{
if (self = [super init]) {
_block = block;
struct CTBlockLiteral *blockRef = (__bridge struct CTBlockLiteral *)block;
_flags = blockRef->flags;
_size = blockRef->descriptor->size;
if (_flags & CTBlockDescriptionFlagsHasSignature) {
void *signatureLocation = blockRef->descriptor;
signatureLocation += sizeof(unsigned long int);
signatureLocation += sizeof(unsigned long int);
if (_flags & CTBlockDescriptionFlagsHasCopyDispose) {
signatureLocation += sizeof(void(*)(void *dst, void *src));
signatureLocation += sizeof(void (*)(void *src));
}
const char *signature = (*(const char **)signatureLocation);
_blockSignature = [NSMethodSignature signatureWithObjCTypes:signature];
}
}
return self;
}
- (BOOL)isCompatibleForBlockSwizzlingWithMethodSignature:(NSMethodSignature *)methodSignature
{
if (_blockSignature.numberOfArguments != methodSignature.numberOfArguments + 1) {
return NO;
}
if (strcmp(_blockSignature.methodReturnType, methodSignature.methodReturnType) != 0) {
return NO;
}
for (int i = 0; i < methodSignature.numberOfArguments; i++) {
if (i == 1) {
// SEL in method, IMP in block
if (strcmp([methodSignature getArgumentTypeAtIndex:i], ":") != 0) {
return NO;
}
if (strcmp([_blockSignature getArgumentTypeAtIndex:i + 1], "^?") != 0) {
return NO;
}
} else {
if (strcmp([methodSignature getArgumentTypeAtIndex:i], [_blockSignature getArgumentTypeAtIndex:i + 1]) != 0) {
return NO;
}
}
}
return YES;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"%@: %@", [super description], _blockSignature.description];
}
@end