菜鸟教程小白 发表于 2022-12-13 08:12:27

ios - Objective-C:将大多数消息转发到另一个对象(在运行时)


                                            <p><h2><code>UIView</code>的子类</h2>
<p>我有一个 <code>UIView</code> 的子类 <code>MyView</code>。</p>
<p>这个子类有一个<code>@property UIView * realView</code>。</p>
<h2>我想做什么</h2>
<p>每当有消息发送到 <code>MyView</code> 时,我都想将其“转发”到 <code>self.realView</code>,除了少数消息。</p>
<p>例如,在 <code>MyView</code> 的实现中,我会有这个覆盖:</p>
<pre><code>- (void)setBackgroundColor:(UIColor *)color
{
    ;
}
</code></pre>
<p><strong>我可以在运行时自动覆盖所有方法,而不是显式覆盖所有方法吗?</strong></p>
<h2>异常(exception)情况</h2>
<p>对于某些方法,我希望有一个明确的控制。例如:</p>
<pre><code>- (void)setFrame:(CGRect)frame
{
    /* do stuff */
   
    ;
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><blockquote>
<p>Instead of overriding explicitly all the methods, can I do it automatically, at the runtime?</p>
</blockquote>

<p>您实现 <code>-forwardInvocation:</code> 方法以将任何无法识别的消息发送到另一个对象。 <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/doc/uid/20000050-forwardInvocation_" rel="noreferrer noopener nofollow"><code>-forwardInvocation</code></a>每当一个对象没有实现作为处理消息的第二次机会传递给它的选择器时,就会调用它。您可以覆盖它以将消息发送到另一个对象(这几乎是 NSProxy 所做的)、记录消息等。</p>

<p>正如@cobbal 在下面指出的那样,<code>-forwardInvocation</code> 将帮助您处理未在您的 superView 中实现的方法,但它不会处理 <em></em> 在 superView 中实现的方法因为您的 <code>MyView</code> 继承了这些实现。例如,如果您想使用 <code>UIView</code> 作为 <code>UIButton</code> 的代理,则 <code>UIButton</code> 特有的所有方法都可以由 <code>-forwardInvocation:</code>,但是<code>UIView</code>定义的不能。为了获得继承方法以外的行为,您当然需要重写。在某些情况下,您可以通过从 <code>NSObject</code> 或 <code>UIResponder</code> 而不是从 <code>UIView</code> 派生 <code>MyView</code> 来解决这个问题,从而避免继承的 <code>UIView</code> 实现,但如果 <code>MyView</code> 需要是一个真实的 View ,你就不得不重写每个方法。</p>

<p>如果您仔细想想,很难想象如果不显式覆盖每个继承的方法,您的目标会如何实现。您说您只想转发<em>大多数</em> 消息,但是糟糕的运行时如何知道您想要转发哪些消息以及不想转发哪些消息?它所能做的就是为给定的选择器寻找一个方法,如果找到就调用它,或者如果没有就采取一些行动(比如调用<code>-forwardInvocation:</code>)。</p>

<p><strong>更新:</strong> @robmayoff 指出 <code>-forwardingTargetForSelector:</code>,我没有想到,但在您的情况下可能是更好的解决方案。但是,它仍然无法处理需要重定向从父类(super class)继承的方法的情况。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - Objective-C:将大多数消息转发到另一个对象(在运行时),我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/24314468/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/24314468/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - Objective-C:将大多数消息转发到另一个对象(在运行时)