项目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:regexoptions:NSRegularExpressionCaseInsensitiveerror:&error];// 对str字符串进行匹配NSArray *matches = [regular matchesInString:stroptions:0range: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文件所有接口名的命令行工具相关推荐

  1. MSSQL-Scripter,一个新的生成T-SQL脚本的SQL Server命令行工具

    这里向大家介绍一个新的生成T-SQL脚本的SQL Server命令行工具:mssql-scripter.它支持在SQL Server.Azure SQL DB以及Azure SQL DW中为数据库生成 ...

  2. lolcat :一个在 Linux 终端中输出彩虹特效的命令行工具

    那些相信 Linux 命令行是单调无聊且没有任何乐趣的人们,你们错了,这里有一些有关 Linux 的文章,它们展示着 Linux 是如何的有趣和"淘气" . Linux命令及Lin ...

  3. 教你写一个ftp协议(文件传输协议)

    一.FTP协议简介 FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制文件的双向传输.同时,它 ...

  4. 如何从文件夹打开dos界面/命令行工具

    ①找到指定文件的文件夹,按住"shift+右键" ②选择"在此处打开命令窗口"选项

  5. jq linux下载文件,linux下的json命令行工具–jq

    jq是一个很轻量却很强大的命令行下的json解析器.jq是json中的"sed"命令,它可以用来slice.filter.map.transform json数据.jq是用C编写的 ...

  6. 【vps】教你写一个自己的随机图API

    [vps]教你写一个自己的随机图API 前言 刚刚开始使用halo博客的时候,我就发现halo博客系统是可以使用随机图当背景的,所以也是使用了网上一些比较火的随机图API. 在上次发现了各种图片API ...

  7. 手把手教你写一个没有服务器的颜值打分小程序,可直接上线

    小程序现在可以说非常火爆了,流量入口非常多.尤其是出了流量主功能以后,普通开发者也能在自己的个人小程序里植入官方广告来获取收入.程序员想赚点外快再合适不过了.今天教大家写一个颜值打分的小程序,利用现成 ...

  8. cmd管道无法接收特定程序返回值_渗透不会反弹shell?来教你写一个cmd的shell

    渗透不会反弹shell?来教你写一个cmd的shell 包含的库: #include #include #include #include #include #pragma comment(lib, ...

  9. 手把手教你写一个spring IOC容器

    本文分享自华为云社区<手把手教你写一个spring IOC容器>,原文作者:技术火炬手. spring框架的基础核心和起点毫无疑问就是IOC,IOC作为spring容器提供的核心技术,成功 ...

最新文章

  1. 《因果科学周刊》第1期:因果社区诚邀加入,打造因果推理共同范式
  2. Spring transaction事务之roll back回滚: rollback-for
  3. activity切换交互动画
  4. Linux 多个cpp文件的编译(Makefile)
  5. Lua 5.1.1 源代码阅读笔记
  6. 【JavaSE02】Java基本语法-概念
  7. css3边框线倾斜,使用CSS3倾斜边框的Div?
  8. python基础——使用__slots__
  9. Ipad 日程管理APP使用心得
  10. 怪兽充电宝 共享充电宝源码
  11. 07: redis分布式锁解决超卖问题
  12. Selenium WebDriver 与 iOS 自动化测试 (做了一些初步的工具对比)
  13. 迅为IMX6ULL开发板Linux RS232/485驱动实验(上)
  14. 【javaWeb学习笔记】HTML,CSS,JS
  15. 高通MSM8953平台调整通话音量
  16. 二维码在线制作免费快速
  17. 小布老师oracle,小布老师-oracle-1
  18. Typo In word‘Wanke‘,取消驼峰命名提示警告
  19. Java基础 实验四 抽象类和接口
  20. 高中心理健康教育教师资格证经验贴

热门文章

  1. h5滚动时侧滑出现_H5触摸事件中如何判断用户滑动方向
  2. docker 安装nginx_Docker18安装Nginx和Apache实验
  3. ios NSString 正则表达式 其它字符
  4. Metasploit search命令使用技巧
  5. mysql2008无法启动_SQL Server 2008突然无法正常启动
  6. java获取内存基址_安卓逆向|菜鸟的FRIDA学习笔记:内存读写
  7. 指定的网络文件夹目前是以其他用户名和密码进行映射的_使用 GitLab CI 与 Argo CD 进行 GitOps 实践
  8. thinkphp mysql desc table_Thinkphp 连接数据库、查询、添加
  9. python连接sqlserver_python 链接sqlserver 写接口实例
  10. mysql oracle 默认事务级别_oracle 默认的事务隔离级别