我正在探索SWIFT中的方法摇摆的概念及其潜在的用例.虽然我知道方法摆动可以是在运行时修改方法行为的强大工具,但我也意识到了与其相关的风险.我想确保我以一种安全有效的方式来处理这项技术.
我读到过,在多线程环境中,方法混乱可能会导致意外行为.在应用方法swizzing时,确保线程安全的最佳实践是什么?有什么推荐的同步机制或模式我应该遵循吗?
我正在探索SWIFT中的方法摇摆的概念及其潜在的用例.虽然我知道方法摆动可以是在运行时修改方法行为的强大工具,但我也意识到了与其相关的风险.我想确保我以一种安全有效的方式来处理这项技术.
我读到过,在多线程环境中,方法混乱可能会导致意外行为.在应用方法swizzing时,确保线程安全的最佳实践是什么?有什么推荐的同步机制或模式我应该遵循吗?
首先,不能以安全的方式进行灌水.从本质上讲,它是危险的.它要求您依赖修改后的类的内部实现细节,这些细节可能会发生变化.我并不是说永远不应该使用它(尽管在超过15年的Cocoa开发中,除了调试之外,我从来不需要编写任何东西),但它必须非常小心地使用.你应该只根据你认为自己对苹果内部的情况以及他们future 可能发生的变化的了解程度来使用它.如果苹果改变了一些你意想不到的东西,这些漏洞可能会非常难以理解.
而不幸的是,当开发人员发现其他开发人员决定使用同样的东西时.永远不要在图书馆里暗地里乱转.(我看着你呢,Firebase.)从技术上讲,多个SWIZE是有效的,它们本身并没有什么问题,但它们放大了当出现问题时事情会变得多么令人困惑.如果您觉得必须在库中使用swizzz,可以通过调用某个"setup"方法让调用者 Select 加入,并清楚地记录您正在应用的swizzes及其行为.
线程化和SWIZZ化的主要问题是,您可能会SWIZZ化已经在做事情的类或对象,而SWIZZ化不是线程安全的.你应该极力避免这样做.一旦对象出现,或在程序中越早越好.理想情况下,类交换应该在+load
方法中完成,以确保它在使用类之前发生.如果这是不可能的,那么main()
.如果这是不可能的,那么application(_:didFinishLaunchingWithOptions:)
.
如果您发现自己需要超过+load
的同步,那么您可能做得太多了,或者以一种太复杂的方式,您应该try 简化您的实现(理想情况下完全go 掉杂乱无章的东西),而不是设计复杂的同步.如果你仍然需要这样做,你可以自己设计一种适合你的情况的方法.
Swizzing最著名的用法是KVO,它引入了很多令人头疼的线程问题.要了解解决KVO线程问题有多难,请参见PMKVObserver.据我所知,这将是如何解决您的问题的最接近的例子.
如果您有像KVO这样动态的东西,最好的答案通常是要求只在主线程上访问该类型.如果它不是你控制的,那可能很难.这就是为什么sizzz是一种棘手的工具的部分原因.