ios swizzle更好的理解 [英] ios swizzle better understanding

查看:52
本文介绍了ios swizzle更好的理解的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有以下代码的UIViewController:

I have a UIViewController with this code:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    NSLog(@"CLASIC");
}

然后我有了一个带有UIViewController类别的框架,该框架确实以这种方式闪烁:

And then I have a framework with a UIViewController category that does swizzling in this manner:

+ (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.

The output is SWIZZLED and then CLASIC.

现在我的问题是:如果在我的视图控制器中,我注释了[super viewDidAppear:animated];然后,已陷入混乱的方法不再被调用;这是为什么?我理解了大多数方面,但似乎这方面有所失误.

Now my question is: if in my viewcontroller I comment the [super viewDidAppear:animated]; then the swizzled method does not get called anymore; why is that? I understood most of the aspects but it seems this one somehow slipped.

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

推荐答案

方法合并用于在运行时使用自定义方法覆盖原始方法.因此,您几乎可以与您编写的自定义方法交换任何方法(包括由Apple实施的私有方法).

Method swizzling is used for overriding original methods with the custom one at runtime. So you can exchange almost any method, (including the private apple implemented ones) with the custom one you wrote.

因此,假设存在一个名为 Parent 的类,该类具有名为 A 的方法,并且您在某个位置与 B 交换了它,就像在 load 方法.从现在开始,父级"下的每个子类都将使用 B ,但原始的"A"方法除外.但是,如果您在子类中覆盖 A 怎么办?根据继承定义,对象将调用其自己的方法,如果尚未实现,则使用其 suprclass的方法.那么,如果您想要父实现,该怎么办?那就是 super 出现的地方.

So imagine there is class named Parent with a method named A and you exchange it with B somewhere before it been called like inside load method. From now on every sub class off 'Parent' will use B except the original 'A' method. But what if you override A in a child class? As Inheritance definition, objects will call their own methods and if they haven't implement it, they use their suprclass's method. So what if you want the parent implementation? Thats where super comes in.

结论

  • 如果重写方法,则不会调用超类(或超类中的自定义交换方法)
  • 如果要使用父级实现,则必须使用 super 关键字进行访问
  • If you override a method, the super class (or the custom exchanged method in superclass) method will not getting called
  • If you want the parent implementation, you have to use super keyword to access it

在这种情况下:

  • 在不调用超级的情况下覆盖子类中的方法意味着您仅覆盖swizzled方法并且不会被调用.
  • Overriding a method in sub class without calling super means you just override swizzled method and it will not getting called.

希望有帮助

这篇关于ios swizzle更好的理解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆