gpt4 book ai didi

ios swizzle更好理解

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:52:54 27 4
gpt4 key购买 nike

我有一个带有此代码的 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。

现在我的问题是:如果在我的 View Controller 中我评论 [super viewDidAppear:animated];然后 swizzled 方法不再被调用;这是为什么?我了解了大部分方面,但似乎不知何故这一方面有所下滑。

- (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");
}

最佳答案

Method swizzling 用于在运行时用自定义方法覆盖原始方法。因此,您几乎可以将任何方法(包括私有(private)苹果实现的方法)与您编写的自定义方法进行交换。

假设有一个名为 Parent 的类使用名为 A 的方法然后你用 B 交换它在它被称为内部之前的某个地方 load方法。从现在开始,'Parent' 的每个子类都将使用 B除了原来的“A”方法。但是,如果您重写 A 会怎样?在 child 类?作为继承定义,对象将调用它们的自己的方法,如果它们没有实现它,它们将使用它们的父类(super class)的方法。那么,如果您想要 parent implementation 怎么办? ?那就是super进来了。

结论

  • 如果您覆盖一个方法,父类(super class)(或父类(super class)中的自定义交换方法)方法将不会被调用
  • 如果你想要父实现,你必须使用super关键字来访问它

在这个问题的案例中:

  • 在不调用 super 的情况下重写子类中的方法意味着您只是重写了 swizzled 方法,它不会被调用。

希望对你有帮助

关于ios swizzle更好理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53188675/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com