iOS runtime實用篇--讓你快速上手一個項目

快速上手一個項目.jpg

前言:

  • 對于一個大項目而言,最煩惱的就是在眾多界面難以找到對應(yīng)的viewController,要改個東西都要花好長的時間去找對應(yīng)的類。
  • 特別是當(dāng)你接手一個大項目的時候,對整體的業(yè)務(wù)邏輯不熟悉,整體的架構(gòu)體系不熟悉,讓你修復(fù)某個頁面的BUG,估計你找這個頁面所對應(yīng)的viewController都要找好久。

思考

  • 能否有一種方式可以快速讓你上手一個大項目?快速找到某個頁面所對應(yīng)的viewController ?

思路

  • 在每一個頁面出現(xiàn)的時候,都打印出哪個類即將出現(xiàn),如下圖所示
Snip20161001_4.png

解決方案

  • 方案1
    • 整個項目中建立一個基類的viewController,然后將項目中所有的viewController都繼承于基類的viewController,然后重寫基類中的viewWillAppear方法
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSString *className = NSStringFromClass([self class]);
    NSLog(@"%@ will appear", className);
}

  • 方案2
  • 給UIViewContoller建立一個分類,在分類里進(jìn)行方法的交換,既保留了原本的方法,又有打印信息
//
//  UIViewController+Swizzling.m
//  CollectionsOfExample
//
//  Created by mac on 16/10/1.
//  Copyright ? 2016年 chenfanfang. All rights reserved.
//

#import "UIViewController+Swizzling.h"

#import <objc/runtime.h>

@implementation UIViewController (Swizzling)

+ (void)load {
    
    //我們只有在開發(fā)的時候才需要查看哪個viewController將出現(xiàn)
    //所以在release模式下就沒必要進(jìn)行方法的交換
#ifdef DEBUG
    
    //原本的viewWillAppear方法
    Method viewWillAppear = class_getInstanceMethod(self, @selector(viewWillAppear:));
    
    //需要替換成 能夠輸出日志的viewWillAppear
    Method logViewWillAppear = class_getInstanceMethod(self, @selector(logViewWillAppear:));
    
    //兩方法進(jìn)行交換
    method_exchangeImplementations(viewWillAppear, logViewWillAppear);
    
#endif
    
}

- (void)logViewWillAppear:(BOOL)animated {
    
    NSString *className = NSStringFromClass([self class]);
    
    //在這里,你可以進(jìn)行過濾操作,指定哪些viewController需要打印,哪些不需要打印
    if ([className hasPrefix:@"UI"] == NO) {
        NSLog(@"%@ will appear",className);
    }
    
    
    //下面方法的調(diào)用,其實是調(diào)用viewWillAppear
    [self logViewWillAppear:animated];
}

@end

優(yōu)缺點分析

  • 方案1 適用于一個新項目,從零開始搭建的項目,建立一個基類controller,這種編程思想非常可取。但對于一個已經(jīng)成型的項目,則方案一行不通,你總不能建議一個基類,讓后將所有的controller繼承的類都改成基類吧?這工程量太大,太麻煩。

上面所述:我個人認(rèn)為“建立一個基類controller,這種編程思想非常可取”,但遭受到簡書朋友們的質(zhì)疑,但我始終堅持自己的觀點。(面相切面編程、繼承的爭論)具體大家可以看評論,擇其優(yōu)而從之。也歡迎大家闡述自己的意見。

個人對AOP和繼承的總結(jié)

就從全新開始搭建一個架構(gòu),到底該使用基類Controller還是直接用AOP的問題上進(jìn)行分析。
有簡書朋友說直接使用AOP的眼觀更加長遠(yuǎn),但我不以為然。若用基類Controller之后,你還可以使用AOP,兩者各施所長。若起初直接用AOP,后期需要使用到基類特性,那只能和你說抱歉了。所以,是否還認(rèn)為一開始直接使用AOP就體現(xiàn)眼觀更加長遠(yuǎn)?可能每個人的編程思想不一,得到的答案也不同。有的簡書朋友或許是考慮到超大項目解耦的問題而始終堅持AOP也是可以理解的。

是否覺得AOP真的很萬能?

AOP編程在某些情況下可控性較差,比如,項目中總有會用到第三方框架,以UIViewController來說吧,或許你并不想自己的操作影響到第三方框架的controller,那么你AOP編程的時候就需要刻意去篩選出需要過濾哪些controller,你就需要去各種找,找到第三方框架哪些是controller,然后進(jìn)行相應(yīng)的過濾。而基類Controller并不存在影響第三方框架的問題。若你非要扯到超大項目,超多模塊,需要解耦問題,那我也不多說什么了,場景不一,沒什么可言。

是否覺得基類Controller耦合性太強(qiáng)?

其實針對耦合性問題,每個人的觀點不同,答案也不一。我個人認(rèn)為,一個基類Controller可以完全替代UIViewController,你就默認(rèn)它就是UIViewController,那么就不存在什么耦合性問題了。簡書朋友所說的耦合性太強(qiáng)我也能理解。

小結(jié):

上面所述僅代表個人的觀點,簡書朋友可理智選取可選部分。
AOP、繼承,沒有誰更優(yōu),不同開發(fā)情況有不同的選擇。始終堅持AOP的簡書朋友們,可能現(xiàn)在你們并沒發(fā)現(xiàn)它的不足,但或許今后的哪一天你們會發(fā)現(xiàn),AOP也有不足。所以個人還是挺堅持自己的想法:基類Controller與AOP共存才能發(fā)揮出最大的優(yōu)勢。

至部分簡書朋友

其實一開始我對一個簡書朋友評論的回復(fù)不當(dāng)(觀點不同,難免有些小情緒),在此表示抱歉。

開發(fā)技術(shù)水很深,謙虛一點還是必要的。有位簡書朋友說的一句話真的很傷人:“估計樓主剛接觸 iOS 開發(fā)不久”,或許你真的對子自己的技術(shù)夠自信。

至簡書朋友們

學(xué)無止境,互相學(xué)習(xí)。廣大簡書朋友們,就以上面的例子請你們“和平”闡述你們的觀點,最好拿出實際例子來與大家分享。

  • 方案2 不論是從零開始搭建的項目,還是已經(jīng)成型的項目,方案2都適用。










最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容