以前觉得这种标题有点偏向于理论,实际开发中怎么会有这种诡异的需求,但是真正遇到了这种硬需求时觉得还是有那么点价值的,理论付诸了实践在此也就做了个整理。
以我私下开发中的一处代码为例,本意是希望有这么一个方法:能够传入一个开始标记(NSString*)一个结束标记(NSString*)一段文字(NSString*) 然后内部在文字中扫描并返回标记包裹内容的范围(NSRange这个范围是忽视标记的)这个范围可能会有多个所以返回的应该是一个装着range的数组。并且顺便把原来字符串中的开始和结束标记全过滤掉,把过滤后的字符串也返回出来。
举个例子就是:传入开始标记“ 结束标记“>” 一段文字 “会议需要叫上和” 然后希望返回一个数组 [{location:6,length:2},{location:9,length:2}] ,和返回处理后的字符串“会议需要叫上彼得和罗宾”。
代码希望能够写成这样,但是是不可能的。
1 |
- (NSArray *,NSMutableString *)scanBeginStr:(NSString *)beginstr endStr:(NSString *)endstr inText:(NSMutableString *)text |
好下面提供三种途径完成此需求。
1.使用字典
这种方法是最low但是最容易理解的,就是如果你需要返回多个对象,直接将多个对象塞在一个字典里面自己设置合理的key并返回字典,字典里面可以放任意数量的“返回值”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
- (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}; } |
这个方法在调用时也就是这样了,非常朴实的代码。
1 2 3 |
NSDictionary* result = [self scanBegin2Str:@"" inText:mutableText]; NSArray *rangeArray = result[@"rangeArray"]; NSMutableString *text = [result[@"text"] mutableCopy]; |
如果觉得字典不舒服也完全可以用模型,自定义一个对象然后给这个对象的各个属性赋值然后再把这个自定义对象返回回去,虽然代码看上去更科学一点但是需要写一些额外的代码并且不能实现任意可配置(每一种属性都必须要提前设定好),这个和上面算是一个相同的思路就不单独再列一条说了。
2.使用指针的指针
这种方法是我实际使用的方法,就是把需要修改的text的指针的指针传进去,然后在方法的内部对这个实参取一下值得到text的指针。然后通过这个指针修改外部的变量的值。代码实现如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
- (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-t">NSMutableString *text = *textPointer; NSMutableArrayت结束标记(NSString*)一段文字(NSString*) 然后内部在文字中扫描并返回标记包裹内容的范围(NSRange这个范围是忽视标记的)这个范围可能会有多个所以返回的应该是一个装着range的数组。并且顺便把原来字符串中的开始和结束标记全过滤掉,把过滤后的字符串也返回出来。
举个例子就是:传入开始标记“ 结束标记“>” 一段文字 “会议需要叫上和” 然后希望返回一个数组 [{location:6,length:2},{location:9,length:2}] ,和返回处理后的字符串“会议需要叫上彼得和罗宾”。 代码希望能够写成这样,但是是不可能的。
好下面提供三种途径完成此需求。 1.使用字典这种方法是最low但是最容易理解的,就是如果你需要返回多个对象,直接将多个对象塞在一个字典里面自己设置合理的key并返回字典,字典里面可以放任意数量的“返回值”。
这个方法在调用时也就是这样了,非常朴实的代码。
如果觉得字典不舒服也完全可以用模型,自定义一个对象然后给这个对象的各个属性赋值然后再把这个自定义对象返回回去,虽然代码看上去更科学一点但是需要写一些额外的代码并且不能实现任意可配置(每一种属性都必须要提前设定好),这个和上面算是一个相同的思路就不单独再列一条说了。 2.使用指针的指针这种方法是我实际使用的方法,就是把需要修改的text的指针的指针传进去,然后在方法的内部对这个实参取一下值得到text的指针。然后通过这个指针修改外部的变量的值。代码实现如下
|