From 5800a0f27b96040124e6f58b616945ea84d8f5cb Mon Sep 17 00:00:00 2001 From: Damien Debin Date: Tue, 9 Sep 2014 18:51:35 +0200 Subject: [PATCH] Bring back fast enumeration to JSONModelArray, lost in commit c4ffee63b64a71c1319b6b5149f60ee88c5f92b8. Add a test for this case. --- JSONModel/JSONModel/JSONModelArray.h | 2 +- JSONModel/JSONModel/JSONModelArray.m | 44 ++++++++++++++++++----- JSONModelDemoTests/UnitTests/ArrayTests.m | 11 ++++-- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/JSONModel/JSONModel/JSONModelArray.h b/JSONModel/JSONModel/JSONModelArray.h index d62875c4..e858ad78 100644 --- a/JSONModel/JSONModel/JSONModelArray.h +++ b/JSONModel/JSONModel/JSONModelArray.h @@ -27,7 +27,7 @@ * of each of the objects stored in the array, it'll be converted to the target model class. * Thus saving time upon the very first model creation. */ -@interface JSONModelArray : NSObject +@interface JSONModelArray : NSObject /** * Don't make instances of JSONModelArray yourself, except you know what you are doing. diff --git a/JSONModel/JSONModel/JSONModelArray.m b/JSONModel/JSONModel/JSONModelArray.m index 8fe77194..6d2ff3dc 100644 --- a/JSONModel/JSONModel/JSONModelArray.m +++ b/JSONModel/JSONModel/JSONModelArray.m @@ -23,7 +23,7 @@ @implementation JSONModelArray Class _targetClass; } -- (id)initWithArray:(NSArray *)array modelClass:(Class)cls +-(id)initWithArray:(NSArray *)array modelClass:(Class)cls { self = [super init]; @@ -34,22 +34,22 @@ - (id)initWithArray:(NSArray *)array modelClass:(Class)cls return self; } -- (id)firstObject +-(id)firstObject { return [self objectAtIndex:0]; } -- (id)lastObject +-(id)lastObject { return [self objectAtIndex:_storage.count - 1]; } -- (id)objectAtIndex:(NSUInteger)index +-(id)objectAtIndex:(NSUInteger)index { return [self objectAtIndexedSubscript:index]; } -- (id)objectAtIndexedSubscript:(NSUInteger)index +-(id)objectAtIndexedSubscript:(NSUInteger)index { id object = _storage[index]; if (![object isMemberOfClass:_targetClass]) { @@ -62,7 +62,7 @@ - (id)objectAtIndexedSubscript:(NSUInteger)index return object; } -- (void)forwardInvocation:(NSInvocation *)anInvocation +-(void)forwardInvocation:(NSInvocation *)anInvocation { [anInvocation invokeWithTarget:_storage]; } @@ -70,14 +70,14 @@ - (void)forwardInvocation:(NSInvocation *)anInvocation -(id)forwardingTargetForSelector:(SEL)selector { static NSArray* overridenMethods = nil; - if (!overridenMethods) overridenMethods = @[@"initWithArray:modelClass:",@"objectAtIndex:",@"objectAtIndexedSubscript:", @"count",@"modelWithIndexValue:",@"description",@"mutableCopy",@"firstObject",@"lastObject"]; + if (!overridenMethods) overridenMethods = @[@"initWithArray:modelClass:",@"objectAtIndex:",@"objectAtIndexedSubscript:", @"count",@"modelWithIndexValue:",@"description",@"mutableCopy",@"firstObject",@"lastObject",@"countByEnumeratingWithState:objects:count:"]; if ([overridenMethods containsObject:NSStringFromSelector(selector)]) { return self; } return _storage; } -- (NSUInteger)count +-(NSUInteger)count { return _storage.count; } @@ -114,4 +114,32 @@ -(NSString*)description return res; } +-(NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state + objects:(id __unsafe_unretained [])stackbuf + count:(NSUInteger)stackbufLength +{ + NSUInteger count = 0; + + unsigned long countOfItemsAlreadyEnumerated = state->state; + + if (countOfItemsAlreadyEnumerated == 0) { + state->mutationsPtr = &state->extra[0]; + } + + if (countOfItemsAlreadyEnumerated < [self count]) { + state->itemsPtr = stackbuf; + while ((countOfItemsAlreadyEnumerated < [self count]) && (count < stackbufLength)) { + stackbuf[count] = [self objectAtIndex:countOfItemsAlreadyEnumerated]; + countOfItemsAlreadyEnumerated++; + count++; + } + } else { + count = 0; + } + + state->state = countOfItemsAlreadyEnumerated; + + return count; +} + @end diff --git a/JSONModelDemoTests/UnitTests/ArrayTests.m b/JSONModelDemoTests/UnitTests/ArrayTests.m index e579b8f8..44e5622c 100644 --- a/JSONModelDemoTests/UnitTests/ArrayTests.m +++ b/JSONModelDemoTests/UnitTests/ArrayTests.m @@ -38,12 +38,19 @@ -(void)testLoading XCTAssertEqualObjects([[repos.repositories[0] class] description], @"GitHubRepoModel", @".properties[0] is not a GitHubRepoModel"); } -- (void)testCount +-(void)testCount { XCTAssertEqualObjects(@(repos.repositories.count), @100, @"wrong count"); } -- (void)testReadArray +-(void)testFastEnumeration +{ + for (GitHubRepoModel *m in repos.repositories) { + XCTAssertNoThrow([m created], @"should not throw exception"); + } +} + +-(void)testReadArray { JSONModelArray *array = [JSONModelArray new];