Just My Life & My Work

[iOS] for 和 forin 的差異

多虧Firebase Crashlytics的幫助,讓我曉得用戶發生哪些崩潰,在後台記錄得非常詳細,可以清楚讓我知道哪一個Class中的哪一行Code是崩潰關鍵!

可看到最近一週,有10次崩潰,影響10個用戶。

事實上發生崩潰的程式碼是本公司前輩所寫,所以一開始我是找到關鍵處沒錯,但是看不出到底有何問題。只好以關鍵字搜尋⋯⋯

‘*** Collection <__NSArrayM: 0x28214f9f0> was mutated while being enumerated.’

原來有好多工程師遇到此崩潰,也將問題與解法描述的詳盡!

現在我就拿自己經手的Code來說明⋯⋯

/**
 Theme: for and forin
 IDE: Xcode 12
 Language: Objective C
 Date: 109/11/20
 Author: HappyMan
 Blog: https://cg2010studio.com/
 */
//會崩潰的寫法:
for(Notification*select in mSelectItems){
    for(Notification*item in mDataItems){
        if([select.objectID isEqual:item.objectID]){
            [mSelectItems replaceObjectAtIndex:[mSelectItems indexOfObject:select] withObject:item];
            break;
        }
    }
}

//解除崩潰的寫法:
for(int i = 0; i < [mSelectItems count]; i++){
    Notification *select = mSelectItems[i];
    for(int j = 0; j < [mDataItems count]; j++){
        Notification *item = mDataItems[j];
        if([select.objectID isEqual:item.objectID]){
            [mSelectItems replaceObjectAtIndex:[mSelectItems indexOfObject:select] withObject:item];
            break;
        }
    }
}

效率

for VS for(… in …)

  1. for 的應用範圍廣基本可以NSArray、NSSet以及C語言的數組等,而for(… in …)僅限於NSArray、NSSet等。
  2. for(… in …) 更簡潔、效率更高。

區別

for循環:
主要用在你已經知道了循環的次數,或者可以明確的得到的循環次數。
比如你要在屏幕上打出100個"Happy World!",或者循環某個數組中的全部內容。
那麼就可以用~
for (int i=0;i<100,i++)
for (int i = 0; i < array.count; i++)
這裡你已經很明確了是100或者得到的array的數組個數。
.
for in循環:
主要是方便遍歷已經知道對像類型的數組,同時不關心索引的情況。
比如已經知道數組裡都是UIButton,那麼你就可以直接用~
for (UIButton *button in array)
這樣你就可以直接透過button直接訪問數組裡的每一個button。
.
另外數組還有一種用block遍歷的方法:
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
//.....
}];

這種方法有一個要注意的地方就是可能會有異步執行的問題最後這三種遍歷方式中,for in的效率是最高的。

for in循環比for循環更高級一些,當你數組裡面的元素對像都一樣,就可以用for in進行遍歷,進行接受的對象跟數組裡面所存儲的是同一型態。

注意事項

如果在for in循環裡,對這個數組進行無論是增加、刪除、修改數組元素位置,都會丟出異常錯誤,表示被遍歷的數組已被銷毀。例如我這次遇到的崩潰:

‘*** Collection <__NSArrayM: 0x28214f9f0> was mutated while being enumerated.’

意思是:枚舉的過程中數組發生了突變。for循環不能自己察覺,但是for in循環可以察覺。

例子

由於最近比較常發活動推播,以至於讓我可以測試到問題所在。簡單地說,原因是用for in取代Array中的元素,於是造成崩潰!

參考:iOS for 和forin 的區別以及注意事項iOS之解决崩溃Collection <__NSArrayM: 0xb550c30> was mutated while being enumerated.

隨意留個言吧:)~

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

標籤雲

%d 位部落客按了讚: