亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS遍歷集合(NSArray、NSDictionary、NSSet)的方法總結

2020-07-26 02:54:30
字體:
來源:轉載
供稿:網友

前言

集合的遍歷操作是開發中最常見的操作之一,從C語言經典的for循環到利用多核cpu的優勢進行遍歷,開發中ios有若干集合遍歷方法,本文通過研究和測試比較了各個操作方法的效率和優略勢,并總結幾個使用集合遍歷時的小技巧。

想到循環遍歷數組、字典這些常見的集合,大家腦子里第一反應就是for循環和快速遍歷,并津津樂道的傳承使用著這些方法,這些已經足夠滿足開發中所有類似的需求,似乎沒有什么需要總結的,其實不然,不信往下看,知道的大神就不要浪費時間了。

第一種方式:for循環

Objective-C是基于C語言的,自然可以使用for循環

遍歷數組:

NSArray *iosArray = @[@"L", @"O", @"V", @"E", @"I", @"O", @"S"];for (int i = 0; i < iosArray.count; i++) {//處理數組中數據NSLog(@"%@", iosArray[i]);}

遍歷數組很簡單沒問題,下面遍歷字典

遍歷字典:

NSDictionary *dict = @{@"1":@"11", @"2":@"22", @"3":@"33"};NSArray *keysArray = [dict allKeys];for (int i = 0; i < keysArray.count; i++) {//根據鍵值處理字典中的每一項NSString *key = keysArray[i];NSString *value = dict[key];NSLog(@"%@", value);}

我們知道字典和set是無序的,所以我們無法根據特定的整數下標來直接訪問其中的值,于是需要先獲取字典中的鍵或者set中的所有對象,這樣就可以在獲取到的有序數組上進行遍歷了。然而創建數組是要額外的開銷的,還會多創建出一個數組對象,他會保留collection中的所有對象,占用了內存。

總結優缺點:

優點:被廣泛使用,容易接受,操作簡單;

缺點:遍歷字典和set是比較繁瑣,會占用比較多的系統資源。

第二種方式:NSEnumerator

NSEnumerator是一個抽象基類,其中定義了2個方法,使其子類實現:

- (nullable ObjectType)nextObject;@property (readonly, copy) NSArray*allObjects;

其中nextObject是關鍵方法,它返回枚舉里的下一個對象。每次調用改方法其,其內部結構都會更新,使得下一次調用方法時能返回下一個對象。等到枚舉中全部的對象都已經返回之后,在調用就會返回nil,表示達到了枚舉的末端。

Foundation框架中的collection都實現了這種遍歷方式,例如:

NSArray *iosArray = @[@"L", @"O", @"V", @"E", @"I", @"O", @"S"];NSEnumerator *enumerator = [iosArray objectEnumerator];//正向遍歷NSEnumerator *enumerator = [iosArray reverseObjectEnumerator];//反向遍歷id object;while ((object = [enumerator nextObject]) != nil) {//處理枚舉器中的數據NSLog(@"%@", object);}

字典和set實現的方式相似,不同的是字典中有key和value,要根據具體的key取出value。同時提供了正向遍歷和反向遍歷。

總結優缺點:

優點:代碼更易讀,不需要定義額外的數組;

缺點:1、無法直接獲取遍歷操作的下標,需要另外聲明變量記錄;

           2、需要自行創建NSEnumerator對象,稍顯麻煩。

第三種方式:快速遍歷

Objective-C 2.0引入了快速遍歷這一功能,快速遍歷與NSEnumerator差不多,然而語法更為簡潔,它為for循環開設了in關鍵字,簡化了遍歷collection所需的語法,例如遍歷數組:

NSArray *iosArray = @[@"L", @"O", @"V", @"E", @"I", @"O", @"S"];for (NSString *obj in iosArray) {//處理數組中的數據NSLog(@"%@", obj);}

遍歷字典也同樣簡單:

NSDictionary *dict = @{@"1":@"11", @"2":@"22", @"3":@"33"};for (NSString *key in dict) {//處理字典的鍵值NSString *value = dict[key];NSLog(@"%@", value);}

反向遍歷可以使用for (NSString *obj in [iosArray reverseObjectEnumerator])

總結優缺點:

優點:語法簡潔,使用方便,效率高;

缺點:1、無法方便獲取當前遍歷的下標;

          2、無法在遍歷過程中修改被遍歷的collection,否則會導致崩潰。

第四種方式:基于塊的遍歷方式

這才是本文的重點,也是筆者極力推薦使用的方法,蘋果封裝了如此高效、優雅、易用的一套接口不用多么浪費。

遍歷數組:

NSArray *iosArray = @[@"L", @"O", @"V", @"E", @"I", @"O", @"S"];[iosArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {NSLog(@"%@", obj);if ([obj isEqualToString:@"E"]) {*stop = YES;}}];

參數說明:obj表示數組中的元素,idx表示元素的下標,*stop可以控制遍歷何時停止,在需要停止時令*stop = YES即可(不要忘記前面的*)。

這種方法清晰明了,數組元素,下標都可直接獲取,就連何時停止都很容易實現,break都可以退休了,遍歷字典也同樣簡單。

遍歷字典:

NSDictionary *dict = @{@"1":@"11", @"2":@"22", @"3":@"33"};[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {NSLog(@"%@", obj);if ([obj isEqualToString:@"22"]) {*stop = YES;}}];

你沒有看錯,就是這么簡單,block直接把字典的key和value都給我們了,再也不用書寫直白而繁瑣的代碼了。

注意:

若已知collection里對象的數據類型,可以修改塊簽名,知道對象的精確類型后,編譯器就可以檢測開發者是否調用了該對象所不具有的方法,并在發現問題時報錯。

NSDictionary *dict = @{@"1":@"11", @"2":@"22", @"3":@"33"};[dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL * _Nonnull stop) {NSLog(@"%@", obj);if ([obj isEqualToString:@"22"]) {*stop = YES;}}];

如代碼,直接把key和value的類型修改成NSString類型。

反向遍歷:

反向遍歷也同樣方便,調用另外一個方法即可:

NSArray *iosArray = @[@"L", @"O", @"V", @"E", @"I", @"O", @"S"];[iosArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {NSLog(@"%@", obj);if ([obj isEqualToString:@"E"]) {*stop = YES;}}];

這個方法相對于正向遍歷多了一個枚舉類型的參數NSEnumerationReverse,打開這個選項就可以反向遍歷了。

并發遍歷:

順著這個枚舉類型的參數,就會引出塊枚舉的另一大優勢:并發遍歷,參數是:NSEnumerationConcurrent,也就是可以同時遍歷collection中的幾個元素,具體數量根據系統資源而定。這樣會充分利用系統資源,高效快捷的完成collection的遍歷,系統底層會通過GCD來處理并發事宜,開發者不需要擔心內存和線程,其他方式若要實現高效的并發遍歷十分有難度。通過塊枚舉遍歷,改變collection并不會引起崩潰,代碼如下:

NSArray *iosArray = @[@"L", @"O", @"V", @"E", @"I", @"O", @"S"];NSMutableArray *iosMutableArray = [NSMutableArray arrayWithArray:iosArray];[iosMutableArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {obj = [NSString stringWithFormat:@"_%@", obj];[iosMutableArray replaceObjectAtIndex:idx withObject:obj];NSLog(@"%@", obj);if ([obj isEqualToString:@"_I"]) {*stop = YES;}}];

優缺點總結:

優點:

1、可以完美實現for循環的所有功能;

2、可以方便獲取集合中的每一項元素;

3、提供了循環遍歷的參數,NSEnumerationReverse用來實現倒序循環。NSEnumerationConcurrent用來實現并發遍歷,兩個參數可以同時使用;

4、這種循環方式效率高,能夠提升程序性能,開發者可以專注于業務邏輯,而不必擔心內存和線程的問題;

5、當開啟NSEnumerationConcurrent選項時,可以實現for循環和快速遍歷無法輕易實現的并發循環功能,系統底層會通過GCD處理并發事宜,這樣可以充分利用系統和硬件資源,達到最優的遍歷效果;

6、可以修改塊簽名,當我們已經明確集合中的元素類型時,可以把默認的簽名id類型修改成已知類型,比如常見的NSString,這樣既可以節省系統資源開銷,也可以防止誤向對象發送不存在的方法是引起的崩潰。

缺點:

1、很多開發者不知道這種遍歷方式;

2、這里使用了block,需要注意在block里容易引起的保留環問題,比如使用self調用方法時,把self轉化成若引用即可打破保留環。如: __weak __typeof(self)weakSelf = self 或者 __weak MyController *weakSelf = self; 在block里使用weakSelf即可。

注意:

使用基于塊的遍歷時是可以修改遍歷的元素的,不會導致崩潰,但是如果要刪除遍歷的元素會導致后面的元素無法遍歷而崩潰,解決辦法有2種,1、一種是復制一份原集合的副本,對副本進行操作,找出所要操作的元素后再處理原集合;2、使用反向遍歷,反向遍歷刪除元素后不會導致崩潰。

總結

在我們還是懵懂的學生時代,還不懂什么叫程序,什么叫開發時,我們就一直有一個疑問:為什么蘋果的設備配置參數不高而運行流暢,看著配置逆天的win機器,偌大沉重的機身,嗡嗡的風扇,滾燙的溫度,直線下降的電量,丑陋的外觀,我們就更好奇蘋果是怎樣做到美觀與性能并存?,F在我們從一個用戶根本察覺不到的簡單的遍歷可以看出些許原因,一個細微之處都是如此追求高效和優雅,這只是蘋果追求的冰山一角,但是我們已然看見了一種偉大的追求極致的精神。我們幸運的成為了蘋果開發者,更感謝上帝賜予人類蘋果這樣一個偉大的公司。

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
69视频在线免费观看| 欧美高清性猛交| 国产亚洲欧美日韩美女| 国产成人精品999| 欧美午夜宅男影院在线观看| 91精品国产高清自在线| 国产日韩欧美一二三区| 92看片淫黄大片欧美看国产片| 国产91精品视频在线观看| 97久久伊人激情网| 丝袜一区二区三区| 久久久亚洲精选| 亚洲欧洲在线免费| 国产精品久久久久久久久久| 久久精品中文字幕免费mv| 国产不卡av在线免费观看| 色香阁99久久精品久久久| 成人激情视频免费在线| 久热在线中文字幕色999舞| 91精品中文在线| 韩国视频理论视频久久| 亚洲一区亚洲二区亚洲三区| www.亚洲人.com| 欧美精品videossex性护士| 成人免费高清完整版在线观看| 亚洲欧美中文日韩在线| 国产成人一区二区三区电影| 精品国产一区二区三区四区在线观看| 中文字幕亚洲无线码在线一区| 欧美在线性视频| 精品久久中文字幕| 欧美精品一二区| 日韩av不卡在线| 亚洲精品一区二区久| 亚洲精品网站在线播放gif| 美女精品久久久| 欧美激情三级免费| 久久久久久久久电影| 国产精品男女猛烈高潮激情| 亚洲国产天堂久久综合| 欧美黑人一区二区三区| 欧美日韩xxxxx| 欧美性受xxx| 亚洲欧美日韩区| 在线看片第一页欧美| 久久九九全国免费精品观看| 亚洲电影天堂av| 午夜剧场成人观在线视频免费观看| 久久躁狠狠躁夜夜爽| 国产精品亚洲美女av网站| 中文字幕久热精品视频在线| 国产精选久久久久久| 在线成人中文字幕| 91中文在线视频| 国产suv精品一区二区三区88区| 欧美激情视频免费观看| 久久69精品久久久久久国产越南| 亚洲国产成人久久综合一区| 国产视频999| 亚洲第一区第一页| 成人有码视频在线播放| 亚洲人成网在线播放| 亚洲视频在线看| 日韩精品丝袜在线| 91精品国产九九九久久久亚洲| 欧美亚洲成人xxx| 久久精品国产亚洲精品| 欧美电影免费在线观看| 97婷婷涩涩精品一区| 欧美日韩国产在线播放| 亚洲成**性毛茸茸| 成人福利视频网| 久久精品免费播放| 国产综合久久久久| 亚洲国产一区自拍| 91精品国产91久久久久福利| 神马久久桃色视频| 久久精品国产亚洲| 日韩久久精品电影| 久久久精品一区二区三区| 欧美最猛性xxxxx免费| 亚洲bt天天射| 国产精品一区二区三区在线播放| 成人性教育视频在线观看| 久久久久久久久中文字幕| 久久人人97超碰精品888| 久久视频在线视频| 97超碰蝌蚪网人人做人人爽| 亚洲一区二区三区毛片| 亚洲第一区中文99精品| 成人黄色av网站| 日韩成人激情影院| 色在人av网站天堂精品| 久久精品成人一区二区三区| www国产精品视频| 久久久久久久一区二区三区| 国产精品va在线播放我和闺蜜| 精品国产一区二区三区久久久狼| 久久免费视频观看| 欧美日韩在线观看视频小说| 成人免费淫片aa视频免费| 欧美电影在线免费观看网站| 国产精选久久久久久| 欧美成人午夜激情在线| 另类视频在线观看| 最近2019中文免费高清视频观看www99| 欧洲美女7788成人免费视频| 亚洲成人黄色网址| 精品亚洲一区二区三区四区五区| 久久激情五月丁香伊人| 欧美国产视频一区二区| 91美女高潮出水| 久久影视三级福利片| 亚洲美女又黄又爽在线观看| 91免费人成网站在线观看18| 国产欧美欧洲在线观看| 91美女片黄在线观| 国产日韩精品一区二区| 97视频在线免费观看| 日韩亚洲精品视频| 亚洲欧美一区二区三区四区| 日韩视频免费观看| 亚洲电影免费观看高清完整版在线观看| 中文字幕亚洲激情| 国产日产亚洲精品| 欧美一区二区三区免费观看| 日韩网站免费观看高清| 7777精品视频| 91香蕉嫩草神马影院在线观看| 日韩欧美在线播放| 日韩在线视频一区| 狠狠久久亚洲欧美专区| 91爱爱小视频k| 国产亚洲欧美日韩精品| 亚洲国产精久久久久久久| 亚洲区中文字幕| 一二美女精品欧洲| 国产一区二区丝袜| 亚洲人在线视频| 色综合视频网站| 中文字幕久久精品| 亚洲色图综合网| 国产一区二区三区视频在线观看| 亚洲一级一级97网| 欧美成人一二三| 福利一区视频在线观看| 国产精品自产拍在线观看中文| 成人疯狂猛交xxx| 亚洲一区国产精品| 国产精品一区av| 精品国偷自产在线视频99| 最近2019好看的中文字幕免费| 亚洲第一精品夜夜躁人人躁| 欧美性69xxxx肥| 午夜精品福利在线观看| 91av免费观看91av精品在线| 国产精品第100页| 亚洲第一网中文字幕| 亚洲美女性生活视频| 国产精品丝袜白浆摸在线| 大量国产精品视频| 国产精品91一区| 国产一区玩具在线观看| 日韩免费在线免费观看|