iOS用三種途徑實現一方法有多個傳回值,ios傳回值

來源:互聯網
上載者:User

iOS用三種途徑實現一方法有多個傳回值,ios傳回值

以前覺得這種標題有點偏向於理論,實際開發中怎麼會有這種詭異的需求,但是真正遇到了這種硬需求時覺得還是有那麼點價值的,理論付諸了實踐在此也就做了個整理。

以我私下開發中的一處代碼為例,本意是希望有這麼一個方法:能夠傳入一個開始標記(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對象只能用基礎資料型別 (Elementary Data Type)。

其實感覺還有別的方法,比如設定N個成員變數在方法內部計算後重新set也完全可以,但是可能大家也知道成員變數多了比較噁心。最近比較火的函數式編程一直在倡導“方法內不能產生副作用”“實現引用透明” ,如果這麼看那後兩種方法就不符合FP的規則了,但是用著也有自己的特色。

 

轉載需註明出處 ,原文連結。

  

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.