首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS 陣列巢狀迴圈崩潰:NSFastEnumeration 錯誤與正確遍歷

     編輯:程式設計綜合問答

錯誤 -[__NSCFString countByEnumeratingWithState:objects:count:]: unrecognized selector 表示嘗試用 for-in 遍歷非集合物件(此處為 NSString)。原始碼 for (NSArray *a in dict) 實際遍歷的是字典的鍵(通常為 NSString),而非值(NSArray)。

錯誤代碼分析


NSDictionary *dict = @{@"key1": @[@"a", @"b"], @"key2": @[@"c"]};
for (NSArray *a in dict) {        // a 實際是 NSString (key)
    for (NSString *s in a) {      // 嘗試遍歷 NSString → 崩潰
    }
}

正確遍歷方式

1. 遍歷所有值


for (NSArray *array in [dict allValues]) {
    for (NSString *str in array) {
        NSLog(@"%@", str);
    }
}

2. 同時取得鍵值


[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
    NSArray *array = (NSArray *)obj;
    for (NSString *str in array) {
        NSLog(@"Key: %@, Value: %@", key, str);
    }
}];

3. 扁平化所有字串


NSArray *allStrings = [dict.allValues valueForKeyPath:@"@unionOfArrays.self"];
for (NSString *str in allStrings) {
    NSLog(@"%@", str);
}

核心概念:NSFastEnumeration 協定

支援 for-in 的類別必須實作 NSFastEnumeration:

  • ✅ NSArray, NSSet, NSDictionary (遍歷鍵), NSOrderedSet
  • ❌ NSString, NSNumber, NSDate, NSData, 自訂類別(未實作協定)

除錯技巧


// 印出實際類型確認
for (id obj in dict) {
    NSLog(@"Type: %@, Class: %@", obj, [obj class]);
    // 輸出: Type: key1, Class: __NSCFString
}

Swift 對應(類型安全,編譯期檢查)


let dict: [String: [String]] = ["key1": ["a", "b"], "key2": ["c"]]

// 遍歷值
for array in dict.values {
    for str in array {
        print(str)
    }
}

// 同時取得鍵值
for (key, array) in dict {
    for str in array {
        print("Key: \(key), Value: \(str)")
    }
}

// 扁平化
let allStrings = dict.values.flatMap { $0 }

理解字典遍歷預設產出鍵而非值,並確認物件是否符合 NSFastEnumeration,即可避免此類崩潰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved