博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS用三种途径实现一方法有多个返回值
阅读量:5975 次
发布时间:2019-06-20

本文共 4845 字,大约阅读时间需要 16 分钟。

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

以我私下开发中的一处代码为例,本意是希望有这么一个方法:能够传入一个开始标记(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

你可能感兴趣的文章
Core python
查看>>
Apache整合Tomcat
查看>>
我的友情链接
查看>>
HTTP协议详解
查看>>
自动生成 java 测试 mock 对象框架 DataFactory-01-入门使用教程
查看>>
Go语言开发(十六)、Go语言常用标准库六
查看>>
小梅科普:白帽子-高端信息安全培训
查看>>
JavaScript学习总结(9)——JS常用函数(一)
查看>>
Maven+SpringMVC+MyBatis实现系统(一)
查看>>
易宝典文章——如何在Exchange 2010中使用PowerShell文本文件批量移动邮箱
查看>>
智能dns 根据地区解析
查看>>
VS2012配置Git并连接到osc@git
查看>>
索尼高清影视技术学院参观观后感
查看>>
jQuery 文本编辑器插件 HtmlBox 使用
查看>>
怎么看自己服务器的带宽?
查看>>
go的错误处理
查看>>
apache2.4.4的安装过程
查看>>
php5.3安装oracle的扩展oci8与pdo_oci
查看>>
发送超长短信的协议格式
查看>>
CentOS 6.x 快速安装L2TP ***
查看>>