以前觉得这种标题有点偏向于理论,实际开发中怎么会有这种诡异的需求,但是真正遇到了这种硬需求时觉得还是有那么点价值的,理论付诸了实践在此也就做了个整理。

以我私下开发中的一处代码为例,本意是希望有这么一个方法:能够传入一个开始标记(NSString*)一个结束标记(NSString*)一段文字(NSString*)  然后内部在文字中扫描并返回标记包裹内容的范围(NSRange这个范围是忽视标记的)这个范围可能会有多个所以返回的应该是一个装着range的数组。并且顺便把原来字符串中的开始和结束标记全过滤掉,把过滤后的字符串也返回出来。

举个例子就是:传入开始标记“<” 结束标记“>” 一段文字 “会议需要叫上<彼得>和<罗宾>”   然后希望返回一个数组 [{location:6,length:2},{location:9,length:2}] ,和返回处理后的字符串“会议需要叫上彼得和罗宾”。

代码希望能够写成这样,但是是不可能的。

- (NSArray *,NSMutableString *)scanBeginStr:(NSString *)beginstr endStr:(NSString *)endstr inText:(NSMutableString *)text

好下面提供三种途径完成此需求。  

1.使用字典

这种方法是最low但是最容易理解的,就是如果你需要返回多个对象,直接将多个对象塞在一个字典里面自己设置合理的key并返回字典,字典里面可以放任意数量的“返回值”。

- (NSDictionary *)scanBeginStr:(NSString *)beginstr endStr:(NSString *)endstr inText:(NSMutableString *)text{NSRange range1,range2;NSUInteger location =0,length=0;range1.location = 0;NSMutableArray *rangeArray = [NSMutableArray array];while (range1.location != NSNotFound) {range1 = [text rangeOfString:beginstr];range2 = [text rangeOfString:endstr];if (range1.location != NSNotFound) {location = range1.location;length = range2.location - range1.location - 1;if (length > 5000)break;[text replaceOccurrencesOfString:beginstr withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, range1.location + range1.length)];[text replaceOccurrencesOfString:endstr withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, range2.location + range2.length - 1)];}[rangeArray addObject:@{@"location":@(location),@"length":@(length)}];}return @{@"rangeArray":rangeArray,@"text":text};
}

这个方法在调用时也就是这样了,非常朴实的代码。

    NSDictionary* result = [self scanBegin2Str:@"<" endStr:@">" inText:mutableText];NSArray *rangeArray = result[@"rangeArray"];NSMutableString *text = [result[@"text"] mutableCopy];

如果觉得字典不舒服也完全可以用模型,自定义一个对象然后给这个对象的各个属性赋值然后再把这个自定义对象返回回去,虽然代码看上去更科学一点但是需要写一些额外的代码并且不能实现任意可配置(每一种属性都必须要提前设定好),这个和上面算是一个相同的思路就不单独再列一条说了。

2.使用指针的指针

这种方法是我实际使用的方法,就是把需要修改的text的指针的指针传进去,然后在方法的内部对这个实参取一下值得到text的指针。然后通过这个指针修改外部的变量的值。代码实现如下

- (NSArray *)scanBeginStr:(NSString *)beginstr endStr:(NSString *)endstr inText:(NSMutableString * *)textPointer{NSRange range1,range2;NSUInteger location =0,length=0;range1.location = 0;NSMutableString *text = *textPointer;NSMutableArray *rangeArray = [NSMutableArray array];while (range1.location != NSNotFound) {range1 = [text rangeOfString:beginstr];range2 = [text rangeOfString:endstr];if (range1.location != NSNotFound) {location = range1.location;length = range2.location - range1.location - 1;if (length > 5000)break;[text replaceOccurrencesOfString:beginstr withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, range1.location + range1.length)];[text replaceOccurrencesOfString:endstr withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, range2.location + range2.length - 1)];}[rangeArray addObject:@{@"location":@(location),@"length":@(length)}];}return rangeArray;
}

这个方法在调用时就这么写了,因为mutabletext的修改是无声无息的。

    NSArray *rangeArray = [self scanBegin3Str:@"<" endStr:@">" inText:&mutableText];// 董铂然博客园

  

3.使用block回调

这种方法实际上严格意义来说不能算返回值,但是能够实现返回值的效果。

- (void)scanBeginStr:(NSString *)beginstr endStr:(NSString *)endstr inText:(NSMutableString *)text result:(void(^)(NSArray *rangeArray,NSMutableString *text))result{NSRange range1,range2;NSUInteger location =0,length=0;range1.location = 0;NSMutableArray *rangeArray = [NSMutableArray array];while (range1.location != NSNotFound) {range1 = [text rangeOfString:beginstr];range2 = [text rangeOfString:endstr];if (range1.location != NSNotFound) {location = range1.location;length = range2.location - range1.location - 1;if (length > 5000)break;[text replaceOccurrencesOfString:beginstr withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, range1.location + range1.length)];[text replaceOccurrencesOfString:endstr withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, range2.location + range2.length - 1)];}[rangeArray addObject:@{@"location":@(location),@"length":@(length)}];}result(rangeArray,text);
}

这个block在使用时可能比较特殊就这么写了

    [self scanBeginStr:@"<" endStr:@">" inText:mutabletext result:^(NSArray *rangeArray, NSMutableString *text) {NSLog(@"%@,%@",rangeArray,text);}];

如果把block的返回值写成一个字典或是模型也可以,但是那就多此一举了。 返回值不能尝试结构体类型,结构体内不能用OC对象只能用基本数据类型。

其实感觉还有别的方法,比如设置N个成员变量在方法内部计算后重新set也完全可以,但是可能大家也知道成员变量多了比较恶心。最近比较火的函数式编程一直在倡导“方法内不能产生副作用”“实现引用透明” ,如果这么看那后两种方法就不符合FP的规则了,但是用着也有自己的特色。

转载需注明出处 ,原文链接。

  

转载于:https://www.cnblogs.com/dsxniubility/p/5122146.html

iOS用三种途径实现一方法有多个返回值相关推荐

  1. 抖音大咖如何寻找广告主?这三种途径值得了解

    抖音大咖如何寻找广告主?抖音用户经过自己的努力,终于成为拥有众多粉丝的抖音大咖.之后,抖音大咖可以利用自身巨大的流量获取利益.接广告就是一种获取利益的方法.而接广告的前提是找到广告主,因此,如何寻找广 ...

  2. Android音乐播放器的获取数据的三种途径

    安卓简易播放器获取数据的三种途径: 1.应用自带数据 2.手机内存卡 3.网络数据 那我们来看看第一种途径: 一.应用自带数据 1.首先要创建一个播放应用类MediaPlayer有一个create的方 ...

  3. 1、计算机可以解决问题的三种途径

    1.计算机可以解决问题的三种途径: 2.基于软件的问题求解方法 是指在用现有的软件解决自己的问题,用对应的软件解决特定的问题,如下: 3.基于程序的问题求解方法 是指通过编写程序来解决的问题,而这个问 ...

  4. 三种途径助物联网改变业务 省心省时省成本

    最近几年,物联网一直在蓬勃发展,如今也变得更加现实.更有意义,而不再是此前只在业界流传的空洞时髦术语. 很难想像会出现这样的一个世界:在这样的世界里,用户的牙刷会告诉用户在刷牙时没有刷到哪一颗牙齿,或 ...

  5. 三种平摊分析的方法分别为_[2020.Vol.188]表征城市树木滞尘:一种景观分析方法...

    表征城市树木滞尘:一种景观分析方法 Characterization of particulate matter deposited on urban tree foliage: A landscap ...

  6. 三种权重的初始化方法

    总结了三种权重的初始化方法,前两种比较常见,后一种是最新的. 1. Gaussian Weights are randomly drawn from Gaussian distributions wi ...

  7. day01 js三种导入html的方法、js书写规范、变量的基本使用、变量提升

    昨天是初学js的第一天,为什么今天才写,我觉得这样可以帮助我复习昨天的知识,加深对js的理解. 我之前学过java的,昨天转入js的学习,对js略有些体会和大家分享下,js刚入门感觉js相对于java ...

  8. (转)Putty server refused our key的三种原因和解决方法

    (转)Putty server refused our key的三种原因和解决方法 参考文章: (1)(转)Putty server refused our key的三种原因和解决方法 (2)http ...

  9. tomcat中三种部署项目的方法(转)

    tomcat中三种部署项目的方法 第一种方法:在tomcat中的conf目录中,在server.xml中的,<host/>节点中添加:  <Context path="/h ...

最新文章

  1. 在ArcEngine下实现图层属性过滤的两种方法
  2. WebMessenger完善后将作为一个开源项目
  3. mysql账号管理系统_简单账号管理系统的实现(b/s、servlet、html、mysql)
  4. SSM框架的搭建(idea)
  5. openresty开发系列32--openresty执行流程之1初始化阶段
  6. 『数据库』数据库编程(概念性的东西,应用一般,甚至有点过时,用来考试)
  7. 使用Spring Boot构建RESTFul服务
  8. java 一次CPU占用过高问题的排查及解决,java基础面试笔试题
  9. Flink 生成数据源
  10. Linux 动态库剖析
  11. 查看perl的模块版本
  12. 浅谈Borg/YARN/Mesos/Torca/Corona一类系统
  13. python 基于模板生成ppt_【Python3】通过模板实现PPT的自动生成
  14. mysql根据用户经纬度查询附近商家,mysql根据经纬度获取附近的商家
  15. CEC2018:动态多目标测试函数DF6~DF9的PS及PF
  16. Netty In Action中文版 - 第二章:第一个Netty程序
  17. USACO-Section 3.2 Feed Ratios(枚举)
  18. Kettle 9.0 源码编译
  19. 移动cmtds设置服务器无响应,总感觉手机的4G信号变差了?跟我这样设置,让你的信号瞬间满格...
  20. 将list对象存储进redis中去

热门文章

  1. [ZZ].NET自动探索式测试工具——Pex
  2. 关于iOS声音识别的框架
  3. 初试 spring web mvc
  4. ORACLE新增DATABASE LINK
  5. Shell十三问总结
  6. PVLAN技术初探-巧用PVLAN优化网络
  7. 「mysql优化专题」90%程序员面试都用得上的索引优化手册(5)
  8. VIM编辑器使用图解
  9. request.getParameterMap()使用
  10. js 获取子节点个数