野火🔥

生命如野火,骄傲而顽强

面试常见:iOS Category


面试非常多候选人,涉及到runtime相关知识Category是一个常见考察点,毕竟这是应用最多的runtime场景。
本文会针对这部分知识问题做一下分解。

1、为什么OC可以用Category给系统类加方法?

2、能不能给系统类加实例?

3、通过objc_setAssociatedObject添加的变量和正常命名的有什么区别?

4、和系统方法同名会怎么发生什么?

5、两个Category同名会怎么样?

6、我一定要调用其中一个被覆盖的Category方法怎么做?

7、+load是怎么做到所有的category的+load都调用的?

8、针对Category同名问题怎么解决?

参考

https://developer.apple.com/library/ios/qa/qa1908/_index.html#//apple_ref/doc/uid/DTS40016829

You can use the OBJC_PRINT_REPLACED_METHODS environment variable to enable extra debug logging that prints a message when methods are replaced by category implementations. When a category is loaded, a message similar to Listing 2 is printed for each method in the category that clashes with an existing method in the original class.

可以设置OBJC_PRINT_REPLACED_METHODS 环境变量来开启debug日志,开启后将会打印出某一方法何时被category实现方法替代了。当category被加载完成后,一条类似清单2展示的消息会被打印出来,这条消息表明了category中的哪一个方法与原始类中的方法名产生了冲突。

Listing 2 Log output when a method is replaced by a category implementation

objc[21184]: REPLACED: -[UIView isOccludedByView:] by category MyCategory (IMP was 0x1873728a0 (/System/Library/Frameworks
/UIKit.framework/UIKit), now 0x10002e700 (/var/mobile/Containers/Bundle/Application/14AFE8C4-EA96-4A51-8D40-F1DAD35CC3D8/.app/)

Important: You should ignore log messages that do not explicitly name your application or a custom framework it links against. Some system frameworks use categories to provide implementations of methods that are defined as stubs in the original class. This causes extra log messages to be emitted when running with the OBJC_PRINT_REPLACED_METHODS environment variable enabled and is expected behavior.
重要提示:你应该忽略那些和你的程序、自定义框架无关的消息。一些系统库使用category来实现原始类中定义的某些方法。当设置OBJC_PRINT_REPLACED_METHODS环境变量为真得时候,请忽略因为上述原因产生的多余日志,因为这是正常行为