关于清理项目资源图片
很长一段时间,我们所做的APP的包都很大,90多M,plus上也有过100多M,但是,现在的包就50+M,期间有三次比较大的瘦身工程,第一次,是刚换leader的时候,大约是16年中,第二次是16年末前后大约2个项目周期期间,第三次是17年中。
第一次瘦身
16年6月之后的两个项目周期,也就是刚开始处理项目,我们做的活儿并不多
- 一是处理代码里打警告,这些警告包括:1-方法废弃警告;2 - 类型转换警告;3 - unsed警告等。
- 二是删除一些重复图片,当时用的是PhotoSweepper,软件只能查出来重复的图片,但是删的时候还是要注意留谁,建议把不准的看下重复图片的像素。
注意处理警告的时候,有些类型转换或者present废弃的情况要自己查验,很有可能出bug的,要 处理好上下文!
这次瘦身让项目看得清爽了一点,毕竟少了几千的警告!!
第二次瘦身
因为我跟leader挨着,平时做的研究性(杂活儿)比较多,我不是处女座,但是我看不惯项目代码的凌乱,我们都知道一点,项目包再大,只要它能正常运行,就不会有人找你麻烦,但是如果你动了代码,出了问题,那么罪当然是你的了。我的leader不赞成我删代码,但是也没有阻止我!于是,我开始第一次删除代码(一些陈旧废弃的代码,但是写这个的人早就离职了,管这个的产品可能也离职了,我遇到过最恐怖的情况,开发,产品,测试,后端懂这块逻辑的都离职了···)。
16年末是我刚接手项目(姑且叫A)里一整个模块的时候,姑且叫模块B,项目B之余A可以说是完全独立的,当在登录的时候,会根据账号权限,如果有B的权限,会提示去A还是B。项目B的代码是14年那种很古老的代码... 我这次主要删的是B里那期提了需求的代码,我会去梳理逻辑,进而会发现无用的类。下面说下我的经验:
- 我们可以在项目里加个类目,这样可以在点击到哪个页面就打印当前是哪个类,当然我们得有足够进入所有页面的账号,可以问产品问测试~~当然你也可以自己捋。
#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
如上,当我们要重构这个页面的时候,跟这个页面有关的,controller,cell,model,viewmodel就都可以删了,甚至没用的图片
*人有多大胆,地有多大产,哪怕是个小需求,更改一点东西,你也可以把整块删了,自己写,反正测试会测的,以后你是想继续糊窗户纸还是住小洋房就看你懒不懒了。
*假如我们这个类是不用的,我们可以先注释掉这个类,command+b,那么接下来你要处理的就是一层层的警告,先把别的类引用的这个不用类的import注释掉,处理完这层警告后,可以继续删除和他相关的cell什么的,同样是先注释再编译,再删除。总结下来就是
*注释本类(C)---->注释引用C的头文件---->删除只与C有关的类---->删除C---->全局搜索引用C的类---->确认是否有用,没有按上循环,有用删除对C的引用
第三次瘦身
这次瘦身小了大约20M的包大小,这次跟第二次的方法基本一样,有一点不同是,这次是删页面,比如,我们要删“我的”这个页面,要知道这个页面有很多cell,点击cell进去又是很多cell,这时候我们要做的是从最里面的页面往外删除,按上边的方法,切不可急躁。
这次删除遇到个问题就是,有些类本身就是废弃在项目里的,所以根本就没引用!!我们知道我们删除代码的时候有1-move to trash 2- move reference,当时打“前辈”估计就是选了2。。。他是多爱你···给你挖的坑!好在我们的项目模块是分文件夹的,日积月累,尽管不那么整洁,但是还是能知道这个类是不是可以删了,所以两点建议:
- 一是项目模块分好文件夹
- 二是项目类名要驼峰按模块从大到小命名
这次瘦身还涉及到了一些非页面类模块,比如网络配置类,通知类,这每个公司都不太一样,我们的老前辈,是在项目里建了个通知中心,每个接口对应不通的通知名,这时候,要清理就比较麻烦了,项目越大越麻烦,如果你们项目分模块,那么恭喜了~如果没分,你就慢慢删吧,从整理页面通知开始。如果分模块了,你就可以整个模块注释,慢慢捋。
项目里还有一些重复的单例类,虽然这种情况不该发生,但是确实有很多类似的工具类,后人不知道前辈已经写好了,或者前辈写的不通用!好吧,我自己写一个,那我也写一个···你懂的~~ 你可以把所有的头文件都合并到另一个去,@implementation也如是,这时候优先对待红色警告,其次是黄色,类似的合并,command + B,改项目里的被你刚刚删除的那个方法!一个个改就好了~~
删除资源图片
链接:https://github.com/tinymind/LSUnusedResources
这个工具可以检测出项目里很大一部分没用的图片或者重复的图片,但是有bug
- 会闪退,大家可以自己改改里面的代码,我们用的时候修改过一次,闪退很少
- 检测出的有可能是有用的图片,我遇到的一种情况是动态图片名字,比如图片有normal(used_n_%@),high(used_h_%@...),诸如这种类似的命名,就可能造成还在用而被你删除的问题。
使用
除了上边的建议另外有几点:
- 建议所有的资源图片都放到一个文件夹,分模块放在子文件夹
- 图片要让设计(美工)上点心,别要一个给一个,很多都重复了,要不开发建个管理系统,要不测试弄一个,这个好很多
- 建议按view,model,viewmodel viewcontroller,vendor,framework等分好文件夹等
- 本来就是精简代码,我却BB了这么多,就是告诉大家,瘦身挺麻烦的,熟能生巧,胆子要大!!!