iOS:Categoryメソッド「上書き」穴埋め実録

1443 ワード

テスト:「xxビューは隠されていません.前は大丈夫でした.」
私「このコードは動いたことないよ.」
このテストはとても頼りになります.私は急いで問題を調べます.
まず事故コードを見つけ、ViewControllerクラスのCategory Aにはこのようなコード(非フィールドコード)があります.
-(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を使用してクラスにメソッドを追加する場合は、ネーミング仕様に注意してください.