清理iOS Mac項(xiàng)目廢棄代碼與無(wú)用圖片

關(guān)于清理項(xiàng)目資源圖片

很長(zhǎng)一段時(shí)間,我們所做的APP的包都很大,90多M,plus上也有過(guò)100多M,但是,現(xiàn)在的包就50+M,期間有三次比較大的瘦身工程,第一次,是剛換leader的時(shí)候,大約是16年中,第二次是16年末前后大約2個(gè)項(xiàng)目周期期間,第三次是17年中。

第一次瘦身

16年6月之后的兩個(gè)項(xiàng)目周期,也就是剛開(kāi)始處理項(xiàng)目,我們做的活兒并不多

  • 一是處理代碼里打警告,這些警告包括:1-方法廢棄警告;2 - 類(lèi)型轉(zhuǎn)換警告;3 - unsed警告等。
  • 二是刪除一些重復(fù)圖片,當(dāng)時(shí)用的是PhotoSweepper,軟件只能查出來(lái)重復(fù)的圖片,但是刪的時(shí)候還是要注意留誰(shuí),建議把不準(zhǔn)的看下重復(fù)圖片的像素。
注意處理警告的時(shí)候,有些類(lèi)型轉(zhuǎn)換或者present廢棄的情況要自己查驗(yàn),很有可能出bug的,要 處理好上下文!

這次瘦身讓項(xiàng)目看得清爽了一點(diǎn),畢竟少了幾千的警告!!

第二次瘦身

因?yàn)槲腋鷏eader挨著,平時(shí)做的研究性(雜活兒)比較多,我不是處女座,但是我看不慣項(xiàng)目代碼的凌亂,我們都知道一點(diǎn),項(xiàng)目包再大,只要它能正常運(yùn)行,就不會(huì)有人找你麻煩,但是如果你動(dòng)了代碼,出了問(wèn)題,那么罪當(dāng)然是你的了。我的leader不贊成我刪代碼,但是也沒(méi)有阻止我!于是,我開(kāi)始第一次刪除代碼(一些陳舊廢棄的代碼,但是寫(xiě)這個(gè)的人早就離職了,管這個(gè)的產(chǎn)品可能也離職了,我遇到過(guò)最恐怖的情況,開(kāi)發(fā),產(chǎn)品,測(cè)試,后端懂這塊邏輯的都離職了···)。
16年末是我剛接手項(xiàng)目(姑且叫A)里一整個(gè)模塊的時(shí)候,姑且叫模塊B,項(xiàng)目B之余A可以說(shuō)是完全獨(dú)立的,當(dāng)在登錄的時(shí)候,會(huì)根據(jù)賬號(hào)權(quán)限,如果有B的權(quán)限,會(huì)提示去A還是B。項(xiàng)目B的代碼是14年那種很古老的代碼... 我這次主要?jiǎng)h的是B里那期提了需求的代碼,我會(huì)去梳理邏輯,進(jìn)而會(huì)發(fā)現(xiàn)無(wú)用的類(lèi)。下面說(shuō)下我的經(jīng)驗(yàn):

  • 我們可以在項(xiàng)目里加個(gè)類(lèi)目,這樣可以在點(diǎn)擊到哪個(gè)頁(yè)面就打印當(dāng)前是哪個(gè)類(lèi),當(dāng)然我們得有足夠進(jìn)入所有頁(yè)面的賬號(hào),可以問(wèn)產(chǎn)品問(wèn)測(cè)試~~當(dāng)然你也可以自己捋。
#import "UIViewController+Tracking.h"
#import <objc/runtime.h>

@implementation UIViewController (Tracking)


+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        swizzMethod(class, @selector(viewWillAppear:), @selector(fang_viewWillAppear:));
        swizzMethod(class, @selector(viewDidAppear:), @selector(fang_viewDidAppear:));
    });
}

static void swizzMethod(Class class, SEL originalSelector, SEL swizzledSelector) {
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    
    BOOL didAddMethod =
    class_addMethod(class,
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));
    
    if (didAddMethod) {
        class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}


#pragma mark - Method Swizzling

- (void)fang_viewWillAppear:(BOOL)animated {
    [self fang_viewWillAppear:animated];
//    NSLog(@"viewWillAppear:%@", self);
}

- (void)fang_viewDidAppear:(BOOL)animated {
    [self fang_viewDidAppear:animated];
//    NSLog(@"[viewDidAppear]:%@", self);
    
    BOOL exclude = YES;
    for (NSString *classString in [self excludeArray]) {
        if ([self isKindOfClass:NSClassFromString(classString)]) {
            exclude = NO;
            break;
        }
    }
    if (exclude) {
        NSLog(@"[搜房幫]:%@", [self class]);
    }
}

- (NSArray *)excludeArray {
    
    NSArray *array = @[@"UINavigationController",
                       @"UIAlertController",
                       @"FangPageViewController",
                       @"UIInputWindowController",
                       @"UICompatibilityInputViewController",
                       @"UIPageViewController"];
    return array;
}
@end

如上,當(dāng)我們要重構(gòu)這個(gè)頁(yè)面的時(shí)候,跟這個(gè)頁(yè)面有關(guān)的,controller,cell,model,viewmodel就都可以刪了,甚至沒(méi)用的圖片
*人有多大膽,地有多大產(chǎn),哪怕是個(gè)小需求,更改一點(diǎn)東西,你也可以把整塊刪了,自己寫(xiě),反正測(cè)試會(huì)測(cè)的,以后你是想繼續(xù)糊窗戶紙還是住小洋房就看你懶不懶了。
*假如我們這個(gè)類(lèi)是不用的,我們可以先注釋掉這個(gè)類(lèi),command+b,那么接下來(lái)你要處理的就是一層層的警告,先把別的類(lèi)引用的這個(gè)不用類(lèi)的import注釋掉,處理完這層警告后,可以繼續(xù)刪除和他相關(guān)的cell什么的,同樣是先注釋再編譯,再刪除??偨Y(jié)下來(lái)就是
*注釋本類(lèi)(C)---->注釋引用C的頭文件---->刪除只與C有關(guān)的類(lèi)---->刪除C---->全局搜索引用C的類(lèi)---->確認(rèn)是否有用,沒(méi)有按上循環(huán),有用刪除對(duì)C的引用

第三次瘦身

這次瘦身小了大約20M的包大小,這次跟第二次的方法基本一樣,有一點(diǎn)不同是,這次是刪頁(yè)面,比如,我們要?jiǎng)h“我的”這個(gè)頁(yè)面,要知道這個(gè)頁(yè)面有很多cell,點(diǎn)擊cell進(jìn)去又是很多cell,這時(shí)候我們要做的是從最里面的頁(yè)面往外刪除,按上邊的方法,切不可急躁。
這次刪除遇到個(gè)問(wèn)題就是,有些類(lèi)本身就是廢棄在項(xiàng)目里的,所以根本就沒(méi)引用??!我們知道我們刪除代碼的時(shí)候有1-move to trash 2- move reference,當(dāng)時(shí)打“前輩”估計(jì)就是選了2。。。他是多愛(ài)你···給你挖的坑!好在我們的項(xiàng)目模塊是分文件夾的,日積月累,盡管不那么整潔,但是還是能知道這個(gè)類(lèi)是不是可以刪了,所以?xún)牲c(diǎn)建議:

  • 一是項(xiàng)目模塊分好文件夾
  • 二是項(xiàng)目類(lèi)名要駝峰按模塊從大到小命名

這次瘦身還涉及到了一些非頁(yè)面類(lèi)模塊,比如網(wǎng)絡(luò)配置類(lèi),通知類(lèi),這每個(gè)公司都不太一樣,我們的老前輩,是在項(xiàng)目里建了個(gè)通知中心,每個(gè)接口對(duì)應(yīng)不通的通知名,這時(shí)候,要清理就比較麻煩了,項(xiàng)目越大越麻煩,如果你們項(xiàng)目分模塊,那么恭喜了~如果沒(méi)分,你就慢慢刪吧,從整理頁(yè)面通知開(kāi)始。如果分模塊了,你就可以整個(gè)模塊注釋?zhuān)邸?/p>

項(xiàng)目里還有一些重復(fù)的單例類(lèi),雖然這種情況不該發(fā)生,但是確實(shí)有很多類(lèi)似的工具類(lèi),后人不知道前輩已經(jīng)寫(xiě)好了,或者前輩寫(xiě)的不通用!好吧,我自己寫(xiě)一個(gè),那我也寫(xiě)一個(gè)···你懂的~~ 你可以把所有的頭文件都合并到另一個(gè)去,@implementation也如是,這時(shí)候優(yōu)先對(duì)待紅色警告,其次是黃色,類(lèi)似的合并,command + B,改項(xiàng)目里的被你剛剛刪除的那個(gè)方法!一個(gè)個(gè)改就好了~~

刪除資源圖片

鏈接:https://github.com/tinymind/LSUnusedResources
這個(gè)工具可以檢測(cè)出項(xiàng)目里很大一部分沒(méi)用的圖片或者重復(fù)的圖片,但是有bug

  • 會(huì)閃退,大家可以自己改改里面的代碼,我們用的時(shí)候修改過(guò)一次,閃退很少
  • 檢測(cè)出的有可能是有用的圖片,我遇到的一種情況是動(dòng)態(tài)圖片名字,比如圖片有normal(used_n_%@),high(used_h_%@...),諸如這種類(lèi)似的命名,就可能造成還在用而被你刪除的問(wèn)題。

使用

LSUnusedResourcesExample.gif

除了上邊的建議另外有幾點(diǎn):

  • 建議所有的資源圖片都放到一個(gè)文件夾,分模塊放在子文件夾
  • 圖片要讓設(shè)計(jì)(美工)上點(diǎn)心,別要一個(gè)給一個(gè),很多都重復(fù)了,要不開(kāi)發(fā)建個(gè)管理系統(tǒng),要不測(cè)試弄一個(gè),這個(gè)好很多
  • 建議按view,model,viewmodel viewcontroller,vendor,framework等分好文件夾等
  • 本來(lái)就是精簡(jiǎn)代碼,我卻BB了這么多,就是告訴大家,瘦身挺麻煩的,熟能生巧,膽子要大?。?!
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,058評(píng)論 25 709
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,568評(píng)論 19 139
  • Podfile.lock 文件最后一次更新Pods時(shí),所有第三方框架的版本號(hào) Pod常用指令區(qū)別:$ pod in...
    ShenYj閱讀 6,822評(píng)論 1 18
  • 白蘭在母親去世后,孤身一人去韓國(guó)找姨媽?zhuān)欢虌屓乙泼窦幽么?,沒(méi)有一個(gè)親人的白蘭選擇留在韓國(guó),但是簽證到期后她...
    timdk閱讀 1,313評(píng)論 0 0
  • ? 本文共1700字,建議閱讀5分鐘 歡迎大家來(lái)到我們的“大咖談考研”欄目,每周的周一至周五,我們會(huì)幫大家問(wèn)至少5...
    9c10357f5f9e閱讀 1,009評(píng)論 1 0

友情鏈接更多精彩內(nèi)容