iOS(Category方法“覆盖”填坑实录)
测试:“xx视图不隐藏了,之前还好的呢。”首先找到出事代码,在ViewController类的Category A中有段这样的代码(非现场代码):
【iOS(Category方法“覆盖”填坑实录)】我:“这块代码没动过啊。”
此测试非常靠谱,心虚的我赶紧查问题...
-(void)hideView:(NSNotification *)notification {
self.testView.hidden = YES;
}
在收到通知之后将视图隐藏,断点了下确实没走,查看了下通知注册和发送逻辑也没问题。既然在分类中,是不是方法被Category的特性“覆盖”了?
于是,全局搜索
hideView:
,果然在此类的另一个Category B中有位同学不知道啥时候加了这样一段代码(为了给ViewController主类瘦身以及功能解耦,给ViewController加了多个Category):-(void)hideView:(BOOL)hidden {
//do something
}
Category B
hideView:
方法成功将Category A中的“覆盖”了,关于Category的“覆盖”问题,美团技术有篇文章讲的很详细:《深入理解Objective-C:Category》 。修改了方法名后问题确实很快就解决了...等等,既然这段代码很久没改过了,为什么之前的版本是好的呢?这勾起了我的兴趣。
经过一会的调查,查明了问题原因:
由于公司在推行组件化,工程异常庞大,目前处于模块间解耦的阶段,平时开发的时候使用CocoaPods搭建了私有库进行开发,测试阶段将CocoaPods中的模块代码直接拷贝到主工程中进行打包(为什么不拷贝打包好的静态库?测试阶段,有问题便于debug)。在拷贝代码的过程中Category A和Category B在Compile Sources中顺序发生了变化,Category B跑到了Category A后面(本来Category B在Category A前面),要知道Category中的方法在类的方法列表中的顺序其实是由编译顺序决定的,后面的方法最终会被加到方法列表的前面,最终实现了方法“覆盖”。其实,Category 的方法“覆盖”问题在大工程中还是比较常见的,常见的是给UIColor,NSString等系统类添加方法后造成了覆盖,在某些工程中有些类甚至出现了4,5个同名方法... 所以,使用Category给类添加方法时一定要注意命名规范。
推荐阅读
- 2020-04-07vue中Axios的封装和API接口的管理
- 对抗抑郁最好的方法
- 怎样用黑谜速冻膜去黑头,|怎样用黑谜速冻膜去黑头, 最有效的去黑头的方法看这!
- 移动端h5调试方法
- iOS中的Block
- 唱歌教学(导致嗓音损坏的几个常见的错误唱歌方法!)
- 拆书方法训练营
- 数组常用方法一
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- 这份史上最经典的3大学习方法,清华北大学霸都在用!