KVC Array Accessors
July 14th, 2009KVC array accessors are notoriously a pain to implement. Really they are just wrapping a bunch of methods around a mutable instance variable, so every implementation is the same. All that’s different is the property name. It’s a shame that Objective-C 2.0 didn’t include an @property and @synthesize for to-many relationships. Until that happens, here’s a way to get something similar with macros:
/*!
\breif Allows easy definition of an array accessor
\details Must provide both the lowercase and uppercase (plural)
name of the property being accessed
*/
#define array_property(low, up) \
- (NSArray *)low; \
- (NSInteger)countOf ## up; \
- (id)objectIn ## up ## AtIndex:(NSInteger)index; \
- (NSArray *) low ## AtIndexes:(NSIndexSet *)indexes; \
- (void)get ## up :(id *)buffer range:(NSRange)range; \
- (void)insertObject:(id)object in ## up ## AtIndex:(NSInteger)index; \
- (void)insert ## up :(NSArray *)objects atIndexes:(NSIndexSet *)indexes; \
- (void)removeObjectFrom ## up ## AtIndex:(NSInteger)index; \
- (void)remove ## up ## AtIndexes:(NSIndexSet *)indexes; \
- (void)replaceObjectIn ## up ## AtIndex:(NSInteger)index withObject:(id)object; \
- (void)replace ## up ## AtIndexes:(NSIndexSet *)indexes with ## up :(NSArray *)replacement;
/*!
\breif Allows easy definition of an array accessor
\details Storage must be an NSMutableArray instance variable. You must alloc and dealloc
this object yourself. Must provide the name of the storage varable as well as
the lowercase and uppercase (plural) name of the property being accessed
*/
#define array_synthesize(storage, low, up) \
- (NSArray *)low { return storage; } \
- (NSInteger)countOf ## up { return [storage count]; } \
- (id)objectIn ## up ## AtIndex:(NSInteger)index { return [storage objectAtIndex:index]; } \
- (NSArray *) low ## AtIndexes:(NSIndexSet *)indexes { return [storage objectsAtIndexes:indexes]; } \
- (void)get ## up :(id *)buffer range:(NSRange)range { [storage getObjects:buffer range:range]; } \
- (void)insertObject:(id)object in ## up ## AtIndex:(NSInteger)index { [storage insertObject:object atIndex:index]; } \
- (void)insert ## up :(NSArray *)objects atIndexes:(NSIndexSet *)indexes { [storage insertObjects:objects atIndexes:indexes]; } \
- (void)removeObjectFrom ## up ## AtIndex:(NSInteger)index { [storage removeObjectAtIndex:index]; } \
- (void)remove ## up ## AtIndexes:(NSIndexSet *)indexes { [storage removeObjectsAtIndexes:indexes]; } \
- (void)replaceObjectIn ## up ## AtIndex:(NSInteger)index withObject:(id)object { [storage replaceObjectAtIndex:index withObject:object]; } \
- (void)replace ## up ## AtIndexes:(NSIndexSet *)indexes with ## up :(NSArray *)replacement { [storage replaceObjectsAtIndexes:indexes withObjects:replacement]; }