#import <Foundation/Foundation.h>
#import <objc/runtime.h>
/**
The AssociantionPolicy enum determines the association memory management type.
*/
typedef enum {
ASSIGN_POLICY = OBJC_ASSOCIATION_ASSIGN,
RETAIN_NONATOMIC_POLICY = OBJC_ASSOCIATION_RETAIN_NONATOMIC,
COPY_NONATOMIC_POLICY = OBJC_ASSOCIATION_COPY_NONATOMIC,
RETAIN_POLICY = OBJC_ASSOCIATION_RETAIN,
COPY_POLICY = OBJC_ASSOCIATION_COPY
}AssociantionPolicy;
@interface NSObject (addRuntimeProperty)
/**
Sets the association between any property for a specific key.
@param property - the associated object
@param key - the key to identify the associated object
@param policy - the memory management policy
*/
- (void)setProperty:(id)property forKey:(char const * const)key withPolicy:(AssociantionPolicy)policy;
/**
returns the associated object for a given key.
@param key - the key to identify the associated object
@return the assiciated object
*/
- (id)getPropertyForKey:(char const * const)key;
/**
determines if there is a object for a given key.
@param key - the key to identify the associated object
@return a boolean value indicating if there is a associated object for a given key
*/
- (BOOL)hasPropertyForKey:(char const * const)key;
#import "NSObject+addRuntimeProperty.h"
@implementation NSObject (addRuntimeProperty)
- (void)setProperty:(id)property forKey:(char const * const)key withPolicy:(AssociantionPolicy)policy {
// validate input
NSAssert(property,@"PROPERTY must not be nil.");
NSAssert(key,@"KEY must not be nil.");
NSAssert(policy!=0, @"POLICY must not be null.");
NSAssert([self isValidPolicy:policy],@"POLICY must be valid.");
// associate object
objc_setAssociatedObject(self, key, property, policy);
}
- (id)getPropertyForKey:(char const * const)key
{
// validate input
NSAssert(key,@"KEY must not be nil.");
NSAssert(objc_getAssociatedObject(self, key)!=nil,@"there is no object for the given KEY.");
// return object
return objc_getAssociatedObject(self, key);
}
- (BOOL)hasPropertyForKey:(char const * const)key
{
// validate input
NSAssert(key,@"KEY must not be nil.");
// return logical result
return objc_getAssociatedObject(self, key) ? YES : NO;
}
/**
checks if a given policy is valid
@param policy - the memory management policy
@return logical result indicating if policy is valid
*/
- (BOOL)isValidPolicy:(AssociantionPolicy)policy
{
switch ( policy ) {
case ASSIGN_POLICY:
case RETAIN_NONATOMIC_POLICY:
case COPY_NONATOMIC_POLICY:
case RETAIN_POLICY:
case COPY_POLICY:
return YES;
default:
return NO;
}
}
@end