Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -520,11 +520,44 @@ - (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state objects: (id *)objects count: (int)count { - OF_UNRECOGNIZED_SELECTOR + OFEnumerator *enumerator; + int i; + + memcpy(&enumerator, state->extra, sizeof(enumerator)); + + if (enumerator == nil) { + void *pool = objc_autoreleasePoolPush(); + + enumerator = [[self keyEnumerator] retain]; + memcpy(state->extra, &enumerator, sizeof(enumerator)); + + objc_autoreleasePoolPop(pool); + } + + state->itemsPtr = objects; + state->mutationsPtr = (unsigned long *)self; + + if (state->state == 1) + return 0; + + for (i = 0; i < count; i++) { + id object = [enumerator nextObject]; + + if (object == nil) { + state->state = 1; + [enumerator release]; + + return i; + } + + objects[i] = object; + } + + return i; } #ifdef OF_HAVE_BLOCKS - (void)enumerateKeysAndObjectsUsingBlock: (of_dictionary_enumeration_block_t)block Index: tests/OFDictionaryTests.m ================================================================== --- tests/OFDictionaryTests.m +++ tests/OFDictionaryTests.m @@ -36,10 +36,11 @@ @end @interface SimpleMutableDictionary: OFMutableDictionary { OFMutableDictionary *_dictionary; + unsigned long _mutations; } @end @implementation SimpleDictionary - (instancetype)init @@ -111,24 +112,10 @@ - (OFEnumerator *)keyEnumerator { return [_dictionary keyEnumerator]; } - -- (OFEnumerator *)objectEnumerator -{ - return [_dictionary objectEnumerator]; -} - -- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state - objects: (id *)objects - count: (int)count -{ - return [_dictionary countByEnumeratingWithState: state - objects: objects - count: count]; -} @end @implementation SimpleMutableDictionary + (void)initialize { @@ -137,17 +124,40 @@ } - (void)setObject: (id)object forKey: (id)key { + bool existed = ([_dictionary objectForKey: key] == nil); + [_dictionary setObject: object forKey: key]; + + if (existed) + _mutations++; } - (void)removeObjectForKey: (id)key { + bool existed = ([_dictionary objectForKey: key] == nil); + [_dictionary removeObjectForKey: key]; + + if (existed) + _mutations++; +} + +- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state + objects: (id *)objects + count: (int)count +{ + int ret = [super countByEnumeratingWithState: state + objects: objects + count: count]; + + state->mutationsPtr = &_mutations; + + return ret; } @end @implementation TestsAppDelegate (OFDictionaryTests) - (void)dictionaryTestsWithClass: (Class)dictionaryClass