随着项目开发的推进和版本迭代,项目中总会出现一些失效的图片资源。这些无效图像通常会增加编译成本和包的大小。一个典型的iOS项目将有大约三分之一的图像未使用。常用的方法有:1、使用工具;2.使用脚本;3、添加图片时写上图片名称的代码;认为此图像未被使用并列出它。这种做法不是很准确:1、遇到imageview动画(即imageView.animationImages),开发者一般喜欢用for循环添加所有图片,这样会导致使用过的图片被列出来;2.Usedifferent添加资源包时,如果两个资源包同名,但是一个资源包中的图片没有被使用,则没有被使用的不会被列出;这样的情况很多。有人会说用第三种方法,但是手动添加比较费时间,也就是下面这个场景:比如我们要跟踪程序中每个viewcontroller显示给用户的次数:的当然,我们可以在每个viewcontroller中添加viewDidAppear;但这太麻烦了,需要在每个视图控制器中编写重复的代码。创建一个子类可能是一种方法,但它需要同时对UIViewController、UITableViewController、UINavigationController和其他UIKit视图控制器进行子类化,这也会产生大量重复代码。上面这段是MethodSwizzling开头的描述。诚然,人工添加难免会遗漏,所以必须采用苹果自己的方法进行集中处理。我们可以通过MethodSwizzling修改UIImage的调用方法,在UIImage中添加打印和使用图片(或路径)的方法,然后写入到一个文件中,最后删除文件中没有出现的图片项目(可以使用脚本删除,方便准确)。这种情况下,我们就可以写出如下MethodSwizzling,如代码所示:#import"ADeanImage+Hook.h"#import#import@implementationUIImage(Hook)+(void)initialize{staticdispatch_once_tonceToken;dispatch_once(&onceToken,^{[selfadeanImageHook];});}+(void)adeanImageHook{[selfimageNameHook];}+(void)imageNameHook//类方法调用方式{Classclass=object_getClass((id)self);SELoriginalSelector=@selector(imageNamed:);SELswizzledSelector=@selector(adean_imageNamed:);MethodoriginalMethod=class_getClassMethod(class,originalSelector);MethodswizzledMethod=class_getClassMethod(class,swizzledSelector);BOOLdidAddMethod=class_addMethod(class,originalSelector,method_getImplementation(swizzledMethod),method_wizzledMethod(s);didAddMethod){class_replaceMethod(类,swizzledSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod));}else{method_exchangeImplementations(originalMethod,swizzledMethod);}}+(UIImage*)adean_imageNamed:(NSString*)name{UIImage*image=[selfadean_imageNamed:name];[selfprintImageNameToLocalWithImageName:name];returnimage;}+(void)printImageNameToLocalWithImageName:(NSString*)name{#ifdefADeanForTest{//打印图片地址ADeanLog(@"adean_msg:imagefile%@",IMAGEFILEFILE);FILE*fp;constchar*imageFilePath=[IMAGEFILEFILEUTF8String];constchar*cImageName=[[NSStringstringWithFormat:@"%@\n",name]UTF8String];/*打开文件*/if((fp=fopen(imageFilePath,"a"))==NULL){ADeanLog("打开文件出错,请检查文件是否存在\n");}else{}fputs(cImageName,fp);fclose(fp);}#endif}@endAppdelegate开始打印所有使用imageNamed的图片时调用[UIImageinitialize]:如果需要打印所有使用过的图片,只需要methodswizzlingUIImage中的所有类方法和实例方法即可。这样,项目测试一次后,所有用到的图片都可以存储在一个图片列表中,只要在脚本语言中删除项目中不在图片列表中的图片即可。注:《Objective-C Runtime 运行时之四:Method Swizzling》和《Method Swizzling》的中文版在原作中漏掉了一段代码注释://Whenswizzlingaclassmethod,usethefollowing://Classclass=object_getClass((id)self);//...//MethodoriginalMethod=class_getClassMethod(class,originalSelector);//MethodswizzledMethod=class_getClassMethod(class,swizzledSelector);byAdorableDeanat江苏南京有见解可以微信联系我。相关兴趣:本文涉及的所有软件均为作者日常使用的工具,不收取任何广告费用。
