美文网首页
检测无用的方法

检测无用的方法

作者: 人仙儿a | 来源:发表于2018-12-07 19:40 被阅读36次

    1.所有的方法

    通过buildSetting->LinkMap设为yes且设map路径生成文件。

    2.真正使用的方法:

    通过otool反编译出selrefs段,如:otool -v -s __DATA __objc_selrefs /Users/a58/Library/Developer/Xcode/DerivedData/bangjob-gwroieegkblzmfbtvtdfeztswqdc/Build/Products/Debug-iphoneos/bangjob.app/bangjob >> bang_sel生成文件。执行文件路径指的是app包里的macho文件。

    3.无用的方法 = 所有方法 - 真正的方法

    所有代码如下:

    /*
     *  所有方法-真正的方法=无用的方法
     */
    - (void)testMinus {
        NSMutableSet *set1 = [self testFile];
        NSMutableSet *set2 = [self testOtoolBangFile];
        NSLog(@"所有方法count:%ld, 真正使用的方法count:%ld", set1.count, set2.count);
        NSLog(@"正在相减...");
        [set1 minusSet:set2];
        NSLog(@"无用方法的count:%ld, 包含set方法", set1.count);
    
        NSMutableSet *containSetterSet = [NSMutableSet set];
        for (NSString *sel in set1) {
            if([sel hasPrefix:@"set"]) {
                [containSetterSet addObject:sel];
            }
        }
        
        NSLog(@"去除set方法 %ld个", containSetterSet.count);
        [set1 minusSet:containSetterSet];
        
        NSLog(@"最终无用方法的count:%ld个", set1.count);
        [[set1 allObjects] writeToFile:@"/Users/a58/noUse-sel" atomically:YES];
        NSLog(@"还是不行,包含getter方法!平时直接用_变量并不调getter方法;并且包含第三方的无用方法");
    }
    
    /*
     *  真正使用的方法。
     *  通过命令otool -v -s __DATA __objc_selrefs /Users/a58/Library/Developer/Xcode/DerivedData/bangjob-gwroieegkblzmfbtvtdfeztswqdc/Build/Products/Debug-iphoneos/bangjob.app/bangjob >> bang_sel 生成文件
     */
    - (NSMutableSet *)testOtoolBangFile {
        
        NSError *error;
        NSString *content = [NSString stringWithContentsOfFile:@"/Users/a58/bang_sel" encoding:NSASCIIStringEncoding error:&error];
        NSString *patternStr = [NSString stringWithFormat:@"__objc_methname:([0-9a-zA-Z_:]+)\\n"];
        NSRegularExpression *regularexpression = [[NSRegularExpression alloc]
                                                  initWithPattern:patternStr
                                                  options:NSRegularExpressionCaseInsensitive
                                                  error:nil];
        
        NSArray<NSTextCheckingResult *> *matches = [regularexpression matchesInString:content options:NSMatchingReportProgress range:NSMakeRange(0, content.length)];
        
        NSLog(@"真正使用的方法:before - count:%ld", matches.count);
        NSMutableSet *set = [NSMutableSet set];
        for (NSTextCheckingResult *result in matches) {
            NSRange range2 = [result rangeAtIndex:1];
            NSString *method = [content substringWithRange:range2];
            [set addObject:method];
        }
        NSLog(@"真正使用的方法:after - count:%ld", set.count);
        return set;
    }
    
    /*
     * 所有的方法。
     * 通过buildSetting->LinkMap设为yes且设map路径生成文件
     */
    - (NSMutableSet *)testFile {
        NSError *error;
        NSString *content = [NSString stringWithContentsOfFile:@"/Users/a58/linkMap.txt" encoding:NSASCIIStringEncoding error:&error];
    //    NSString *patternStr = [NSString stringWithFormat:@"([+-]\\[.+\\s(.+)\\])"];
        NSString *patternStr = [NSString stringWithFormat:@"[+-]\\[[0-9a-zA-Z_]+\\s([0-9a-zA-Z_:]+)\\]\\n"];
        NSRegularExpression *regularexpression = [[NSRegularExpression alloc]
                                                  initWithPattern:patternStr
                                                  options:NSRegularExpressionCaseInsensitive
                                                  error:nil];
        
        NSArray<NSTextCheckingResult *> *matches = [regularexpression matchesInString:content options:NSMatchingReportProgress range:NSMakeRange(0, content.length)];
        
        NSLog(@"所有方法:before - count:%ld", matches.count);
        NSLog(@"正在去重...");
        NSMutableSet *set = [NSMutableSet set];
        for (NSTextCheckingResult *result in matches) {
            NSRange range2 = [result rangeAtIndex:1];
            NSString *method = [content substringWithRange:range2];
            [set addObject:method];
        }
        NSLog(@"所有方法 after - count:%ld", set.count);
        [[set allObjects] writeToFile:@"/Users/a58/link-sel" atomically:YES];
        return set;
    }
    
    

    打印的日志如下:

    2018-12-07 19:28:41.909175+0800 TestMachO2[80125:1791939] 所有方法:before - count:53987
    2018-12-07 19:28:41.909410+0800 TestMachO2[80125:1791939] 正在去重...
    2018-12-07 19:28:41.971372+0800 TestMachO2[80125:1791939] 所有方法 after - count:27194
    2018-12-07 19:28:42.014835+0800 TestMachO2[80125:1791939] 真正使用的方法:before - count:23796
    2018-12-07 19:28:42.042791+0800 TestMachO2[80125:1791939] 真正使用的方法:after - count:23796
    2018-12-07 19:28:42.042883+0800 TestMachO2[80125:1791939] 所有方法count:27194, 真正使用的方法count:23796
    2018-12-07 19:28:42.042911+0800 TestMachO2[80125:1791939] 正在相减...
    2018-12-07 19:28:42.053201+0800 TestMachO2[80125:1791939] 无用方法的count:6709, 包含set方法
    2018-12-07 19:28:42.055813+0800 TestMachO2[80125:1791939] 去除set方法 2633个
    2018-12-07 19:28:42.057631+0800 TestMachO2[80125:1791939] 最终无用方法的count:4076个
    2018-12-07 19:28:42.062334+0800 TestMachO2[80125:1791939] 还是不行,包含getter方法!平时直接用_变量并不调getter方法;并且包含第三方的无用方法
    

    结论

    最终找出无用的方法4076个。
    但是getter方法和第三方的库的方法混在其中,无法剔除,只能通过人工一个一个查看来进行筛选。所以还需要尝试其它更好的方式!!!

    相关文章

      网友评论

          本文标题:检测无用的方法

          本文链接:https://www.haomeiwen.com/subject/gqyxhqtx.html