mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-10 22:45:59 +05:45
104 lines
3.9 KiB
Objective-C
104 lines
3.9 KiB
Objective-C
// Copyright 2020 Google LLC
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#import "FirebasePerformance/Sources/Instrumentation/FPRClassInstrumentor.h"
|
|
#import "FirebasePerformance/Sources/Instrumentation/FPRClassInstrumentor_Private.h"
|
|
|
|
#import "FirebasePerformance/Sources/Common/FPRDiagnostics.h"
|
|
#import "FirebasePerformance/Sources/Instrumentation/FPRSelectorInstrumentor.h"
|
|
|
|
/** Use ivars instead of properties to reduce message sending overhead. */
|
|
@interface FPRClassInstrumentor () {
|
|
// The selector instrumentors associated with this class.
|
|
NSMutableSet<FPRSelectorInstrumentor *> *_selectorInstrumentors;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation FPRClassInstrumentor
|
|
|
|
#pragma mark - Public methods
|
|
|
|
- (instancetype)init {
|
|
FPRAssert(NO, @"%@: please use the designated initializer.", NSStringFromClass([self class]));
|
|
return nil;
|
|
}
|
|
|
|
- (instancetype)initWithClass:(Class)aClass {
|
|
self = [super init];
|
|
if (self) {
|
|
FPRAssert(aClass, @"You must supply a class in order to instrument its methods");
|
|
_instrumentedClass = aClass;
|
|
_selectorInstrumentors = [[NSMutableSet<FPRSelectorInstrumentor *> alloc] init];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (nullable FPRSelectorInstrumentor *)instrumentorForClassSelector:(SEL)selector {
|
|
return [self buildAndAddSelectorInstrumentorForSelector:selector isClassSelector:YES];
|
|
}
|
|
|
|
- (nullable FPRSelectorInstrumentor *)instrumentorForInstanceSelector:(SEL)selector {
|
|
return [self buildAndAddSelectorInstrumentorForSelector:selector isClassSelector:NO];
|
|
}
|
|
|
|
- (void)swizzle {
|
|
for (FPRSelectorInstrumentor *selectorInstrumentor in _selectorInstrumentors) {
|
|
[selectorInstrumentor swizzle];
|
|
}
|
|
}
|
|
|
|
- (BOOL)unswizzle {
|
|
for (FPRSelectorInstrumentor *selectorInstrumentor in _selectorInstrumentors) {
|
|
[selectorInstrumentor unswizzle];
|
|
}
|
|
[_selectorInstrumentors removeAllObjects];
|
|
return _selectorInstrumentors.count == 0;
|
|
}
|
|
|
|
#pragma mark - Private methods
|
|
|
|
/** Creates and adds a selector instrumentor to this class instrumentor.
|
|
*
|
|
* @param selector The selector to build and add to this class instrumentor;
|
|
* @param isClassSelector If YES, then the selector is a class selector.
|
|
* @return An FPRSelectorInstrumentor if the class/selector combination exists, nil otherwise.
|
|
*/
|
|
- (nullable FPRSelectorInstrumentor *)buildAndAddSelectorInstrumentorForSelector:(SEL)selector
|
|
isClassSelector:
|
|
(BOOL)isClassSelector {
|
|
FPRSelectorInstrumentor *selectorInstrumentor =
|
|
[[FPRSelectorInstrumentor alloc] initWithSelector:selector
|
|
class:_instrumentedClass
|
|
isClassSelector:isClassSelector];
|
|
if (selectorInstrumentor) {
|
|
[self addSelectorInstrumentor:selectorInstrumentor];
|
|
}
|
|
return selectorInstrumentor;
|
|
}
|
|
|
|
/** Adds a selector instrumentors to an existing running list of instrumented selectors.
|
|
*
|
|
* @param selectorInstrumentor A non-nil selector instrumentor, whose SEL objects will be swizzled.
|
|
*/
|
|
- (void)addSelectorInstrumentor:(nonnull FPRSelectorInstrumentor *)selectorInstrumentor {
|
|
if ([_selectorInstrumentors containsObject:selectorInstrumentor]) {
|
|
FPRAssert(NO, @"You cannot instrument the same selector (%@) twice",
|
|
NSStringFromSelector(selectorInstrumentor.selector));
|
|
}
|
|
[_selectorInstrumentors addObject:selectorInstrumentor];
|
|
}
|
|
|
|
@end
|