KWCaptureSpy.m 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #import "KWCaptureSpy.h"
  2. #import "KWObjCUtilities.h"
  3. #import "KWNull.h"
  4. #import "KWValue.h"
  5. #import "NSInvocation+KiwiAdditions.h"
  6. #import "NSMethodSignature+KiwiAdditions.h"
  7. @interface KWCaptureSpy()
  8. @property (nonatomic, strong) id argument;
  9. @end
  10. @implementation KWCaptureSpy {
  11. NSUInteger _argumentIndex;
  12. }
  13. - (id)initWithArgumentIndex:(NSUInteger)index {
  14. self = [super init];
  15. if (self) {
  16. _argumentIndex = index;
  17. }
  18. return self;
  19. }
  20. - (id)argument {
  21. if (!_argument) {
  22. @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Argument requested has yet to be captured." userInfo:nil];
  23. }
  24. if(_argument == [KWNull null]) {
  25. return nil;
  26. }
  27. else {
  28. return _argument;
  29. }
  30. }
  31. - (void)object:(id)anObject didReceiveInvocation:(NSInvocation *)anInvocation {
  32. if (!_argument) {
  33. NSMethodSignature *signature = [anInvocation methodSignature];
  34. const char *objCType = [signature messageArgumentTypeAtIndex:_argumentIndex];
  35. if (KWObjCTypeIsObject(objCType) || KWObjCTypeIsClass(objCType)) {
  36. void* argumentBuffer = NULL;
  37. [anInvocation getMessageArgument:&argumentBuffer atIndex:_argumentIndex];
  38. id argument = (__bridge id)argumentBuffer;
  39. if (KWObjCTypeIsBlock(objCType)) {
  40. _argument = [argument copy];
  41. } else {
  42. if(argument == nil) {
  43. _argument = [KWNull null];
  44. } else {
  45. _argument = argument;
  46. }
  47. }
  48. } else {
  49. NSData *data = [anInvocation messageArgumentDataAtIndex:_argumentIndex];
  50. _argument = [KWValue valueWithBytes:[data bytes] objCType:objCType];
  51. }
  52. }
  53. }
  54. @end