Skip to content

Commit

Permalink
Merge pull request jsonmodel#238 from smartapps-fr/master
Browse files Browse the repository at this point in the history
Bring back fast enumeration to JSONModelArray
  • Loading branch information
icanzilb committed Jan 21, 2015
2 parents bcf6bd7 + 5800a0f commit b3126fb
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 11 deletions.
2 changes: 1 addition & 1 deletion JSONModel/JSONModel/JSONModelArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <NSFastEnumeration>

/**
* Don't make instances of JSONModelArray yourself, except you know what you are doing.
Expand Down
44 changes: 36 additions & 8 deletions JSONModel/JSONModel/JSONModelArray.m
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand All @@ -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]) {
Expand All @@ -62,22 +62,22 @@ - (id)objectAtIndexedSubscript:(NSUInteger)index
return object;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
-(void)forwardInvocation:(NSInvocation *)anInvocation
{
[anInvocation invokeWithTarget:_storage];
}

-(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;
}
Expand Down Expand Up @@ -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
11 changes: 9 additions & 2 deletions JSONModelDemoTests/UnitTests/ArrayTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down

0 comments on commit b3126fb

Please sign in to comment.