Episode #81

Associated Objects

10 minutes
Published on August 22, 2013

This video is only available to subscribers. Get access to this video and 572 others.

In this episode I add a block-based tap handler to UIButton, and discovering the limitation that categories can't define ivars or properties. To fix this, we use the objective-c runtime to add associated object storage. We also identify a block retain cycle and discuss a fix.

Episode Links

Adding a block-based handler to UIButton

// UIButton+Blocks.h
typedef void (^ButtonBlock)();
@interface UIButton (Blocks)
- (void)addTargetWithBlock:(ButtonBlock)block;
@end

// UIButton+Blocks.m
#import "UIButton+Blocks.h"
#import <objc/runtime.h>

static char BlockKey;

@implementation UIButton (Blocks)

- (void)addTargetWithBlock:(ButtonBlock)block {
    objc_setAssociatedObject(self, &BlockKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC);

    [self addTarget:self action:@selector(executeBlock)
   forControlEvents:UIControlEventTouchUpInside];
}

- (void)executeBlock {
    ButtonBlock block = objc_getAssociatedObject(self, &BlockKey);
    if (block) {
        block();
    }
}

@end

Note that the object will release all associated storage upon dealloc so there is no need to manually clean these up.