IOS Swizzle лучше понять
У меня есть UIViewController с этим кодом:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"CLASIC");
}
А потом у меня есть фреймворк с категорией UIViewController, который делает свистлинг следующим образом:
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL viewWillAppearSelector = @selector(viewDidAppear:);
SEL viewWillAppearLoggerSelector = @selector(logged_viewDidAppear:);
Method originalMethod = class_getInstanceMethod(self, viewWillAppearSelector);
Method extendedMethod = class_getInstanceMethod(self, viewWillAppearLoggerSelector);
method_exchangeImplementations(originalMethod, extendedMethod);
});
}
- (void)logged_viewDidAppear:(BOOL)animated
{
[self logged_viewDidAppear:animated];
NSLog(@"SWIZZLED");
}
Выход SWIZZLED, а затем CLASIC.
Теперь мой вопрос: если в моем viewcontroller я комментирую [super viewDidAppear:animated]; тогда закрученный метод больше не вызывается; это почему? Я понял большинство аспектов, но кажется, что этот как-то ускользнул.
- (void)viewDidAppear:(BOOL)animated
{
// we comment this and this will trigger the swizzled method not being called anymore
//[super viewDidAppear:animated];
NSLog(@"CLASIC");
}
// ========================
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL viewWillAppearSelector = @selector(viewDidAppear:);
SEL viewWillAppearLoggerSelector = @selector(logged_viewDidAppear:);
Method originalMethod = class_getInstanceMethod(self, viewWillAppearSelector);
Method extendedMethod = class_getInstanceMethod(self, viewWillAppearLoggerSelector);
method_exchangeImplementations(originalMethod, extendedMethod);
});
}
- (void)logged_viewDidAppear:(BOOL)animated
{
[self logged_viewDidAppear:animated];
NSLog(@"SWIZZLED");
}
1 ответ
Метод Swizzling используется для замены оригинальных методов на пользовательские во время выполнения. Таким образом, вы можете обмениваться практически любым методом (включая методы, реализованные в частном яблоке) с тем, который вы написали.
Итак, представьте, что есть класс с именем Parent
с методом по имени A
и вы обмениваетесь с B
где-то, прежде чем он был назван как внутри load
метод. С этого момента каждый подкласс от "Родителя" будет использовать B
кроме оригинального метода "А". Но что если вы переопределите A
в детском классе? Как определение Наследования, объекты будут вызывать свои собственные методы, и если они не реализовали это, они используют метод своего suprclass. Так что, если вы хотите parent implementation
? Это где super
приходит в.
Заключение
- Если вы переопределите метод, метод суперкласса (или метод с пользовательским обменом в суперклассе) не будет вызван
- Если вы хотите родительскую реализацию, вы должны использовать супер ключевое слово для доступа к ней
И в этом случае вопросы:
- Переопределение метода в подклассе без вызова super означает, что вы просто переопределите метод swizzled, и он не будет вызван.
Надеюсь, поможет