前言:
- 對于一個大項目而言,最煩惱的就是在眾多界面難以找到對應(yīng)的viewController,要改個東西都要花好長的時間去找對應(yīng)的類。
- 特別是當(dāng)你接手一個大項目的時候,對整體的業(yè)務(wù)邏輯不熟悉,整體的架構(gòu)體系不熟悉,讓你修復(fù)某個頁面的BUG,估計你找這個頁面所對應(yīng)的viewController都要找好久。
思考
- 能否有一種方式可以快速讓你上手一個大項目?快速找到某個頁面所對應(yīng)的viewController ?
思路
- 在每一個頁面出現(xiàn)的時候,都打印出哪個類即將出現(xiàn),如下圖所示
解決方案
- 方案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都適用。