Wrap an NSMutableArray, extending it to implement KVC compliance for a "count" property.
/* Header: ItemStore.h
#import <Foundation/Foundation.h>
@interface ItemStore : NSObject <NSFastEnumeration>
@property (nonatomic, assign, readonly) NSUInteger count;
@end
*/
#import "ItemStore.h"
@interface ItemStore ()
@property (nonatomic, strong) NSMutableArray* array;
@property (nonatomic, assign, readwrite) NSUInteger count;
@end
@implementation ItemStore
- (instancetype)init
{
self = [super init];
if (self) {
_array = [NSMutableArray array];
_count = [_array count];
}
return self;
}
#pragma mark - Message forwarding to mutable array
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
if ([[self array] respondsToSelector:[anInvocation selector]]) {
NSUInteger count = [[self array] count];
[anInvocation invokeWithTarget:[self array]];
if (count != [[self array] count]) {
// If we instead set the count every time, we fire off a KVO when we don't want one!
self.count = [[self array] count];
}
}
else {
[super forwardInvocation:anInvocation];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
NSMethodSignature* signature = [super methodSignatureForSelector:selector];
if (!signature) {
signature = [[self array] methodSignatureForSelector:selector];
}
return signature;
}
#pragma mark - Facilitate fast enumeration
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
objects:(id __unsafe_unretained *)buffer
count:(NSUInteger)len
{
return [[self array] countByEnumeratingWithState:state objects:buffer count:len];
}
@end