Associated objects are useful when you want to add functionality to existing classes which requires holding state.
For example, adding a activity indicator to every UIView:
Objective-C Implementation
#import <objc/runtime.h>
static char ActivityIndicatorKey;
@implementation UIView (ActivityIndicator)
- (UIActivityIndicatorView *)activityIndicator {
return (UIActivityIndicatorView *)objc_getAssociatedObject(self, &ActivityIndicatorKey);
}
- (void)setActivityIndicator: (UIActivityIndicatorView *)activityIndicator {
objc_setAssociatedObject(self, &ActivityIndicatorKey, activityIndicator, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)showActivityIndicator {
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray];
[self setActivityIndicator:activityIndicator];
activityIndicator.center = self.center; activityIndicator.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
[activityIndicator startAnimating];
[self addSubview: activityIndicator];
}
- (void)hideActivityIndicator {
UIActivityIndicatorView * activityIndicator = [self activityIndicator];
if (activityIndicator != nil) { [[self activityIndicator] removeFromSuperview]; }
}
@end
You can also access the Objective-C runtime through Swift:
Swift Code
extension UIView {
private struct AssociatedKeys { static var activityIndicator = “UIView.ActivityIndicatorView” }
private var activityIndicatorView: UIActivityIndicatorView? { get { return objc_getAssociatedObject(self, &AssociatedKeys.activityIndicator) as? UIActivityIndicatorView } set (activityIndicatorView) { objc_setAssociatedObject(self, &AssociatedKeys.activityIndicator, activityIndicatorView, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } }
func showActivityIndicator() { activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray) activityIndicatorView.center = center activityIndicatorView.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin]
activityIndicatorView.startAnimating()
addSubview(activityIndicatorView)