菜鸟教程小白 发表于 2022-12-12 14:59:21

ios swizzle 更好理解


                                            <p><p>我有一个带有此代码的 UIViewController:</p>

<pre><code>- (void)viewDidAppear:(BOOL)animated
{
    ;
    NSLog(@&#34;CLASIC&#34;);
}
</code></pre>

<p>然后我有一个带有 UIViewController 类别的框架,它以这种方式运行:</p>

<pre><code>+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&amp;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
{
    ;

    NSLog(@&#34;SWIZZLED&#34;);
}
</code></pre>

<p>输出是 SWIZZLED,然后是 CLASIC。</p>

<p>现在我的问题是:如果在我的 ViewController 中我评论了 ;然后不再调用 swizzled 方法;这是为什么?我理解了大部分方面,但似乎这一方面不知何故滑倒了。</p>

<pre><code>- (void)viewDidAppear:(BOOL)animated
{
    // we comment this and this will trigger the swizzled method not being called anymore
    //;
    NSLog(@&#34;CLASIC&#34;);
}

// ========================

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&amp;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
{
    ;

    NSLog(@&#34;SWIZZLED&#34;);
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>方法调配用于在运行时用自定义方法覆盖原始方法。因此,您几乎可以将任何方法(包括私有(private)苹果实现的方法)与您编写的自定义方法进行交换。</p>

<p>所以想象有一个名为 <code>Parent</code> 的类有一个名为 <code>A</code> 的方法,然后你在某个地方与 <code>B</code> 交换它,然后像在里面一样调用它</code>加载</code>方法。从现在开始,'Parent' 之外的每个子类都将使用 <code>B</code> 除了原始的 'A' 方法。但是,如果您在子类中覆盖 <code>A</code> 怎么办?作为继承定义,对象将调用它们的<strong>自己的方法</strong>,如果它们没有实现它,它们会使用它们的<strong>父类(super class)的方法</strong>。那么如果你想要<code>父实现</code>呢?这就是 <code>super</code> 的用武之地。</p>

<p><strong>结论</strong></p>

<ul>
<li>如果你重写一个方法,父类(super class)(或父类(super class)中的自定义交换方法)方法将不会被调用</li>
<li>如果你想要父实现,你必须使用 <strong>super</strong> 关键字来访问它</li>
</ul>

<p>在这个问题的情况下:</p>

<ul>
<li>在不<strong>调用 super</strong> 的情况下覆盖子类中的方法意味着您只需覆盖 swizzled 的方法,它不会被调用。</li>
</ul>

<p>希望对你有帮助</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios swizzle 更好理解,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/53188675/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/53188675/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios swizzle 更好理解