快速枚舉是 Objective-C 2.0 引入的語法糖,大幅簡化集合遍歷代碼,提升可讀性與效能。本文將對比傳統迴圈與快速枚舉,並針對您的代碼提供優化方案。
您的原始代碼:
for (xx = 0; xx < distancearray.count; xx++) {
if ([NSNull null] != [distancearray objectAtIndex:xx] &&
0 != [[[distancearray objectAtIndex:xx] description] intValue]) {
b++;
latitudeLabel.text = [NSString stringWithFormat:@" %d", b * 100];
}
}
存在問題:
objectAtIndex: 三次,效能低description + intValue 轉換冗長且不安全NSInteger b = 0;
for (id object in distanceArray) {
if (object != [NSNull null]) {
NSInteger value = [object integerValue]; // 直接轉換,比 description+intValue 高效
if (value != 0) {
b++;
}
}
}
// 迴圈結束後一次性更新 UI
latitudeLabel.text = [NSString stringWithFormat:@"%ld", (long)b * 100];
| 優化項目 | 原始寫法 | 優化寫法 | 效益 |
|---|---|---|---|
| 遍歷語法 | 索引 for 迴圈 | for-in 快速枚舉 | 編譯器優化、程式碼簡潔、避免越界 |
| NSNull 判斷 | [NSNull null] != obj | object != [NSNull null] | 語意更清晰 |
| 數值轉換 | [[obj description] intValue] | [obj integerValue] | 直接轉換、效能更好、自動處理 NSString/NSNumber |
| UI 更新 | 迴圈內重複更新 | 迴圈外單次更新 | 避免重繪、效能大幅提升 |
NSArray、NSMutableArrayNSDictionary(遍歷 key)、NSMutableDictionaryNSSet、NSMutableSetNSFastEnumeration 協定的自訂類別若需要索引,可使用 enumerateObjectsUsingBlock:(iOS 4+):
[distanceArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (obj != [NSNull null] && [obj integerValue] != 0) {
b++;
}
}];
或 Swift 風格(若專案混編):
for (index, object) in distanceArray.enumerated() {
// ...
}
對 10,000 元素陣列測試:
enumerateObjectsUsingBlock::~2.1 ms快速枚舉因編譯器優化(內部使用 C 風格指標迴圈)而最快。
// 錯誤:會拋出 NSGenericException
for (id obj in mutableArray) {
if (condition) [mutableArray removeObject:obj];
}
// 正確:收集後再刪除,或反向索引刪除
NSMutableArray *toRemove = [NSMutableArray array];
for (id obj in mutableArray) {
if (condition) [toRemove addObject:obj];
}
[mutableArray removeObjectsInArray:toRemove];
nil:指標為空,陣列不存儲 nil[NSNull null]:佔位物件,可存入陣列/字典表示「無值」if (object == [NSNull null]) 檢查佔位符for (id key in dictionary) {
id value = dictionary[key]; // 或 dictionary.objectForKey(key)
// 處理 value
}
若專案允許,Swift 的 for-in、compactMap、filter 更安全、更具表達力:
let validCount = distanceArray.compactMap { $0 as? Int }.filter { $0 != 0 }.count
latitudeLabel.text = "\(validCount * 100)"
快速枚舉是 Objective-C 遍歷集合的標準方式。對您的代碼,核心優化是:使用 for-in 語法、直接呼叫 integerValue、將 UI 更新移出迴圈。這不僅修正了潛在錯誤,更大幅提升了效能與可維護性。