FBRetainCycleUtils.m 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /**
  2. * Copyright (c) 2016-present, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. */
  9. #import "FBRetainCycleUtils.h"
  10. #import <objc/runtime.h>
  11. #import "FBBlockStrongLayout.h"
  12. #import "FBClassStrongLayout.h"
  13. #import "FBObjectiveCBlock.h"
  14. #import "FBObjectiveCGraphElement.h"
  15. #import "FBObjectiveCNSCFTimer.h"
  16. #import "FBObjectiveCObject.h"
  17. #import "FBObjectGraphConfiguration.h"
  18. static BOOL _ShouldBreakGraphEdge(FBObjectGraphConfiguration *configuration,
  19. FBObjectiveCGraphElement *fromObject,
  20. NSString *byIvar,
  21. Class toObjectOfClass) {
  22. for (FBGraphEdgeFilterBlock filterBlock in configuration.filterBlocks) {
  23. if (filterBlock(fromObject, byIvar, toObjectOfClass) == FBGraphEdgeInvalid) {
  24. return YES;
  25. }
  26. }
  27. return NO;
  28. }
  29. FBObjectiveCGraphElement *FBWrapObjectGraphElementWithContext(FBObjectiveCGraphElement *sourceElement,
  30. id object,
  31. FBObjectGraphConfiguration *configuration,
  32. NSArray<NSString *> *namePath) {
  33. if (_ShouldBreakGraphEdge(configuration, sourceElement, [namePath firstObject], object_getClass(object))) {
  34. return nil;
  35. }
  36. FBObjectiveCGraphElement *newElement;
  37. if (FBObjectIsBlock((__bridge void *)object)) {
  38. newElement = [[FBObjectiveCBlock alloc] initWithObject:object
  39. configuration:configuration
  40. namePath:namePath];
  41. } else {
  42. if ([object_getClass(object) isSubclassOfClass:[NSTimer class]] &&
  43. configuration.shouldInspectTimers) {
  44. newElement = [[FBObjectiveCNSCFTimer alloc] initWithObject:object
  45. configuration:configuration
  46. namePath:namePath];
  47. } else {
  48. newElement = [[FBObjectiveCObject alloc] initWithObject:object
  49. configuration:configuration
  50. namePath:namePath];
  51. }
  52. }
  53. return (configuration && configuration.transformerBlock) ? configuration.transformerBlock(newElement) : newElement;
  54. }
  55. FBObjectiveCGraphElement *FBWrapObjectGraphElement(FBObjectiveCGraphElement *sourceElement,
  56. id object,
  57. FBObjectGraphConfiguration *configuration) {
  58. return FBWrapObjectGraphElementWithContext(sourceElement, object, configuration, nil);
  59. }