教你写一个可以找到.m文件所有接口名的命令行工具

教你写一个可以找到.m文件所有接口名的命令行工具,第1张

概述项目github 出发点 今天工作中写了一个工具类,在.m中完成所有功能后,发觉把所有接口从.m中拷贝到.h中声明,好麻烦啊,所以就考虑写个命令行工具来做这些工作。 想要达到的结果 我们设计这个小工具,在终端中直接运行,传入一个.m文件路径参数,输出其中所有的方法名。 input:> fti PWFileController.m output:- (NSString *)bytesTo

项目github

出发点

今天工作中写了一个工具类,在.m中完成所有功能后,发觉把所有接口从.m中拷贝到.h中声明,好麻烦啊,所以就考虑写个命令行工具来做这些工作。

想要达到的结果

我们设计这个小工具,在终端中直接运行,传入一个.m文件路径参数,输出其中所有的方法名。

input:> fti PWfileController.m output:- (Nsstring *)bytesToAvaiUnit:(long long)bytes;- (long long) fileSizeAtPath:(Nsstring*) filePath;- (long long) folderSizeAtPath:(Nsstring*) folderPath;- (voID) clearFolderAtPath:(Nsstring*) folderPath;- (float)getTotaldiskSpace;- (Nsstring *)getHomeDirectory;
开始

第一步新建一个mac的命令行(Command line Tool)项目,这种项目只有一个main.m文件,内容如下

#import <Foundation/Foundation.h>int main(int argc,const char * argv[]) {    @autoreleasepool {        // insert code here...        NSLog(@"Hello,World!");    }    return 0;}

这里先分析一下原理,首先.m文件中的C函数方法是不带自动内存池的,所以要在C方法中使用ObjC代码,必须使用@autoreleasepool大括号括起来,这样才能保证在C方法结束后,栈内存能够释放。

其次,main函数中的argc参数,代表命令行中参数的个数,argv这个char数组,是每个参数的内容。

所以我们首先判断argc的个数,这里要注意,shell中的命令本身占一个参数位,所以没有任何参数的时候,argc应该为1。

if(argc<=1) return 0; //当argc<=1直接退出程序

接着我们要获取命令行输入的第二个参数,也就是.m文件路径

Nsstring* filePath = [[Nsstring alloc] initWithCString:argv[1] enCoding:NSUTF8StringEnCoding];

如果文件不存在,则结束程序

if(![[NSfileManager defaultManager] fileExistsAtPath:filePath]){   NSLog(@"文件不存在");   return 0;}

接着我们在main函数之前声明一个找接口的方法,这个方法要用C语言方法的格式声明

NSArray* findInterface (Nsstring* text);

然后实现它,注意要加@autoreleasepool

NSArray* findInterface (Nsstring* text){    @autoreleasepool {        Nsstring *regex = @"-\s?\(.*?\).*?(?=\n|$|\{)";        Nsstring *str = text;        NSError *error;        NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:regex                                                                                 options:NSRegularExpressionCaseInsensitive                                                                                   error:&error];        // 对str字符串进行匹配        NSArray *matches = [regular matchesInString:str                                            options:0                                              range:NSMakeRange(0,str.length)];                NSMutableArray* result = [NSMutableArray arrayWithCapacity:matches.count];        // 遍历匹配后的每一条记录        for (NSTextCheckingResult *match in matches) {            NSRange range = [match range];            Nsstring *mStr = [str substringWithRange:range];            [result addobject:mStr];        }                return [result copy];    }}

这一段正则表达式的搜索没有特别要说明的,关于NSRegularExpression这个类的正则的用法,比较简单,参考上面代码就行,所以我简单说下正则的匹配规则

-\s?\(.*?\).*?(?=\n|$|\{)

-符号开头,在第一个左括号中间有若干空格,然后有若干空格和字符,然后有一个右括号,接下来又是若干个空格和字符,结尾要匹配三个,换行符\n,字符串结尾$和左大括号{

这样我们在main方法中读取文件内容,然后调用这个方法即可输出所有的接口名。

Nsstring* s = [[Nsstring alloc] initWithContentsOffile:filePath enCoding:NSUTF8StringEnCoding error:nil];Nsstring* f = [[findInterface(s) componentsJoinedByString:@";\n"] stringByAppendingString:@";"];NSLog(@"result:\n%@",f);

完整的代码请参考 项目github

使用

这个项目通过菜单 Product -> Archive 可以发布released版本的运行程序,然后将其拷贝到/usr/local/bin目录下,即可在terminal中直接使用。

注意我为了方便,把Archive出来的运行程序名,简化为fti

补充

类方法匹配,把正则中的-改为(-|\+)即可。
换行的方法,可以根据{来匹配,把(?=\n|$|\{)改为[^;]*?(?=\{)
原理各位自己分析。

因为修改了匹配规则,我们需要对抓取的内容进行一些处理,
在findInterface方法中,我们去掉检索内容的换行符和;,用stringByReplacingOccurrencesOfString方法实现

for (NSTextCheckingResult *match in matches) {            NSRange range = [match range];            Nsstring *mStr = [str substringWithRange:range];            mStr = [mStr stringByReplacingOccurrencesOfString:@"\n" withString:@""];            mStr = [mStr stringByReplacingOccurrencesOfString:@";" withString:@""];            mStr = format(mStr); //这个方法在下面的内容zh            [result addobject:mStr];}

然后我们增加一个format方法,来把多行函数,格式化成标准的一行函数。

Nsstring* format (Nsstring* string){    @autoreleasepool {        string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];        NSArray *components = [string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];                components = [components filteredArrayUsingPredicate:[nspredicate predicateWithFormat:@"self <> ''"]];                string = [components componentsJoinedByString:@" "];        return string;    }}
总结

以上是内存溢出为你收集整理的教你写一个可以找到.m文件所有接口名的命令行工具全部内容,希望文章能够帮你解决教你写一个可以找到.m文件所有接口名的命令行工具所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1049353.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存