Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds new runtime addition void class_swizzleSelectorWithBlock(Class c…
…lass, SEL originalSelector, SEL unusedSelector, id block);.
- Loading branch information
1 parent
62baaee
commit 99d3dc7
Showing
10 changed files
with
612 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
CTObjectiveCRuntimeAdditions/CTObjectiveCRuntimeAdditions/CTBlockDescription.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// | ||
// CTBlockDescription.h | ||
// CTBlockDescription | ||
// | ||
// Created by Oliver Letterer on 01.09.12. | ||
// Copyright (c) 2012 olettere. All rights reserved. | ||
// | ||
|
||
struct CTBlockLiteral { | ||
void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock | ||
int flags; | ||
int reserved; | ||
void (*invoke)(void *, ...); | ||
struct block_descriptor { | ||
unsigned long int reserved; // NULL | ||
unsigned long int size; // sizeof(struct Block_literal_1) | ||
// optional helper functions | ||
void (*copy_helper)(void *dst, void *src); // IFF (1<<25) | ||
void (*dispose_helper)(void *src); // IFF (1<<25) | ||
// required ABI.2010.3.16 | ||
const char *signature; // IFF (1<<30) | ||
} *descriptor; | ||
// imported variables | ||
}; | ||
|
||
enum { | ||
CTBlockDescriptionFlagsHasCopyDispose = (1 << 25), | ||
CTBlockDescriptionFlagsHasCtor = (1 << 26), // helpers have C++ code | ||
CTBlockDescriptionFlagsIsGlobal = (1 << 28), | ||
CTBlockDescriptionFlagsHasStret = (1 << 29), // IFF BLOCK_HAS_SIGNATURE | ||
CTBlockDescriptionFlagsHasSignature = (1 << 30) | ||
}; | ||
typedef int CTBlockDescriptionFlags; | ||
|
||
|
||
|
||
@interface CTBlockDescription : NSObject | ||
|
||
@property (nonatomic, readonly) CTBlockDescriptionFlags flags; | ||
@property (nonatomic, readonly) NSMethodSignature *blockSignature; | ||
@property (nonatomic, readonly) unsigned long int size; | ||
@property (nonatomic, readonly) id block; | ||
|
||
- (id)initWithBlock:(id)block; | ||
|
||
- (BOOL)isCompatibleForBlockSwizzlingWithMethodSignature:(NSMethodSignature *)methodSignature; | ||
|
||
@end |
74 changes: 74 additions & 0 deletions
74
CTObjectiveCRuntimeAdditions/CTObjectiveCRuntimeAdditions/CTBlockDescription.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.