Proyectos de Subversion Iphone Microlearning

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// Copyright 2020 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
 
15
#import "FirebasePerformance/Sources/Instrumentation/FPRClassInstrumentor.h"
16
#import "FirebasePerformance/Sources/Instrumentation/FPRClassInstrumentor_Private.h"
17
 
18
#import "FirebasePerformance/Sources/Common/FPRDiagnostics.h"
19
#import "FirebasePerformance/Sources/Instrumentation/FPRSelectorInstrumentor.h"
20
 
21
/** Use ivars instead of properties to reduce message sending overhead. */
22
@interface FPRClassInstrumentor () {
23
  // The selector instrumentors associated with this class.
24
  NSMutableSet<FPRSelectorInstrumentor *> *_selectorInstrumentors;
25
}
26
 
27
@end
28
 
29
@implementation FPRClassInstrumentor
30
 
31
#pragma mark - Public methods
32
 
33
- (instancetype)init {
34
  FPRAssert(NO, @"%@: please use the designated initializer.", NSStringFromClass([self class]));
35
  return nil;
36
}
37
 
38
- (instancetype)initWithClass:(Class)aClass {
39
  self = [super init];
40
  if (self) {
41
    FPRAssert(aClass, @"You must supply a class in order to instrument its methods");
42
    _instrumentedClass = aClass;
43
    _selectorInstrumentors = [[NSMutableSet<FPRSelectorInstrumentor *> alloc] init];
44
  }
45
  return self;
46
}
47
 
48
- (nullable FPRSelectorInstrumentor *)instrumentorForClassSelector:(SEL)selector {
49
  return [self buildAndAddSelectorInstrumentorForSelector:selector isClassSelector:YES];
50
}
51
 
52
- (nullable FPRSelectorInstrumentor *)instrumentorForInstanceSelector:(SEL)selector {
53
  return [self buildAndAddSelectorInstrumentorForSelector:selector isClassSelector:NO];
54
}
55
 
56
- (void)swizzle {
57
  for (FPRSelectorInstrumentor *selectorInstrumentor in _selectorInstrumentors) {
58
    [selectorInstrumentor swizzle];
59
  }
60
}
61
 
62
- (BOOL)unswizzle {
63
  for (FPRSelectorInstrumentor *selectorInstrumentor in _selectorInstrumentors) {
64
    [selectorInstrumentor unswizzle];
65
  }
66
  [_selectorInstrumentors removeAllObjects];
67
  return _selectorInstrumentors.count == 0;
68
}
69
 
70
#pragma mark - Private methods
71
 
72
/** Creates and adds a selector instrumentor to this class instrumentor.
73
 *
74
 *  @param selector The selector to build and add to this class instrumentor;
75
 *  @param isClassSelector If YES, then the selector is a class selector.
76
 *  @return An FPRSelectorInstrumentor if the class/selector combination exists, nil otherwise.
77
 */
78
- (nullable FPRSelectorInstrumentor *)buildAndAddSelectorInstrumentorForSelector:(SEL)selector
79
                                                                 isClassSelector:
80
                                                                     (BOOL)isClassSelector {
81
  FPRSelectorInstrumentor *selectorInstrumentor =
82
      [[FPRSelectorInstrumentor alloc] initWithSelector:selector
83
                                                  class:_instrumentedClass
84
                                        isClassSelector:isClassSelector];
85
  if (selectorInstrumentor) {
86
    [self addSelectorInstrumentor:selectorInstrumentor];
87
  }
88
  return selectorInstrumentor;
89
}
90
 
91
/** Adds a selector instrumentors to an existing running list of instrumented selectors.
92
 *
93
 *  @param selectorInstrumentor A non-nil selector instrumentor, whose SEL objects will be swizzled.
94
 */
95
- (void)addSelectorInstrumentor:(nonnull FPRSelectorInstrumentor *)selectorInstrumentor {
96
  if ([_selectorInstrumentors containsObject:selectorInstrumentor]) {
97
    FPRAssert(NO, @"You cannot instrument the same selector (%@) twice",
98
              NSStringFromSelector(selectorInstrumentor.selector));
99
  }
100
  [_selectorInstrumentors addObject:selectorInstrumentor];
101
}
102
 
103
@end