gpt4 book ai didi

objective-c - 如何在 Objective-C 中实现或修改方法调度表?

转载 作者:搜寻专家 更新时间:2023-10-30 19:55:59 26 4
gpt4 key购买 nike

有时,设置方法调度表很有用,这样调用方法 A 调用 AImpl() 方法,而在另一时间调用方法 A 调用 BImpl()。对于系统自动调用的方法(例如委托(delegate)方法),如何在 Objective-C 中完成此操作?

例如,如果系统第一次调用 viewDidAppear,我希望它调用 viewAppearFirstTime,而随后调用 viewDidAppear 将命中一个完全不同的方法体(而不是使用 bool 标志在代码中进行 if-else 检查)。

另一个例子,假设 UIView 的 drawRect 在应用程序中被调用得非常频繁,如果第一次调用的 drawRect 与后续调用的不同,我不想包含一个 if-test,因为那是代码更难阅读并且第一次之后也不需要检查。

最佳答案

我会在这里警告:您所描述的特定情况可能不应该以这种方式完成。几乎可以肯定,它太聪明了,应该分成 viewDidLoadviewWillAppear 而不是 viewWillAppear 的两个版本。也就是说,问题确实出现了。

对此,我的首选解决方案是保留一个指向我想要执行的操作的 SEL。例如,我在复杂的异步事件之后将这种技术用于“下一步行动”:

if (self.nextActionSelector != NULL)
{
[self performSelector:self.nextActionSelector];
}

为此,您可以使用随时间变化的 viewWillAppearSelector,并且 viewWillAppear 会调用它指向的任何内容。

Ben 推荐的 Method Swizzling 在某些情况下很有用,但更常见的是当您尝试修改某些现有对象的行为而不是您自己的行为时。它真的可以使调试变得有趣……好吧,实际上并不有趣。痛苦。非常痛苦。

除此之外,我还会查看 -forwardInvocation:,它可用于响应您未直接实现的消息。然后您可以重写调用以调用您真正想要的方法。但是,这并不是真正的使用方式。它用于透明地将调用转发给其他对象。但至少调试它并没有那么困难,因为调试器会到达您期望的位置。

通常在这种情况下,我寻找的不是 bool 值,而是我之前被运行过的证据。检查 view 是否已经设置,或者其他一些第一次初始化的值,所以我不需要一个特殊的变量,所以我对清除我的状态的事情有弹性(比如 iPhone 的实践当内存紧张时倾倒东西)。在可能的情况下,我让这些东西在它们的 getter 中自行初始化,而不是让某些外部方具有特殊的首次逻辑。保持这里的逻辑简单使得维护更容易,嘿,NSInvocation 非常慢(好吧,除非在一个紧密的循环中,否则你不会注意到它,但它比方法调用慢大约 500 倍在我的测试中。也就是说,我并不是建议根据性能做出这个决定,只是考虑可维护性)。

关于objective-c - 如何在 Objective-C 中实现或修改方法调度表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/997243/

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