多虧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 …)
- for 的應用範圍廣基本可以NSArray、NSSet以及C語言的數組等,而for(… in …)僅限於NSArray、NSSet等。
- for(… in …) 更簡潔、效率更高。
區別
for (int i=0;i<100,i++)for (int i = 0; i < array.count; i++)
for (UIButton *button in array)
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { //..... }];
這種方法有一個要注意的地方就是可能會有異步執行的問題,最後這三種遍歷方式中,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.。
隨意留個言吧:)~