features

In Objective-C, there are classes that can add methods without modifying the source code; When you look at someone else’s open source code, you can add attributes dynamically. And it’s running, which is awesome.

To use the runtime library, you must first import objc/ Runtime.h

The following functions can be used:

OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

To create an association, use the Objective-C runtime function objc_setAssociatedObject to associate one object with another. This function takes four arguments: the source object, the keyword, the associated object, and an associated policy. Of course, keywords and association policies need to be discussed further here.

The keyword is a pointer to void. Each associated keyword must be unique. Usually static variables are used as keywords.

An association object can be used as a way to hold the key object from the source object, such as the color in the label below, where objc_setAssociatedObject passes the associated object, Get the block in objc_getAssociatedObject(id object, const void *key). For example, the block in the View below is defined in objc_setAssociatedObject. And implement it after objc_getAssociatedObject gets a block.

The association policy indicates whether related objects are associated by assigning, retaining references, or copying. And whether the association is atomic or nonatomic. The association policy is similar to that used when declaring attributes. This association strategy is expressed by using predefined constants.

This function

OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)

__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);

Usage scenarios

1. Category uses objc_setAssociatedObject/objc_getAssociatedObject to add attributes

Properties are just get/set methods. We can dynamically add methods to a class using objc_setAssociatedObject/objc_getAssociatedObject

UILabel+Associate.h

#import <UIKit/UIKit.h>

@interface UILabel (Associate)

– (void) setFlashColor:(UIColor *) flashColor;

– (UIColor *) getFlashColor;

@end

UILabel+Associate.m

#import”UILabel+Associate.h”

#import<object/runtime.h>

@implementationUILabel (Associate)

static char flashColorKey;

– (void) setFlashColor:(UIColor *) flashColor{

objc_setAssociatedObject(self,&flashColorKey, flashColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

– (UIColor *) getFlashColor{

return objc_getAssociatedObject(self, &flashColorKey);

}@end

Calling code:

UILabel *lab =[[UILabel alloc] init];

[lab setFlashColor:[UIColor redColor]];

NSLog(@”%@”, [lab getFlashColor]);

2. Simple use of objc_setAssociatedObject and Block

The expansion of the UIAlertView

.h files

#import <UIKit/UIKit.h>

typedf void(^successBlock)(NSInteger buttonIndex);

@interface UIAlertView(Block)

– (void)showWithBlock:(successBlock)block;

@end

.m files

#import”UIAlertView+Block.h”

#import

static const char alertKey;

@implementationUIAlertView(Block)

– (void)showWithBlock:(successBlock)block{

if(block)    {        

objc_setAssociatedObject(self, &alertKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

self.delegate=self;    

}   

[self show]; }

– (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

{    successBlock block = objc_getAssociatedObject(self, &alertKey);    

block(buttonIndex); }

@end

The expansion of the UIButton

.h files

#import

typedef void(^btnBlock)();

@interfaceUIButton(Block)

– (void)handelWithBlock:(btnBlock)block;

@end

.m files

#import”UIButton+Block.h”

#import <objc/runtime.h>

static const char btnKey;

@implementationUIButton(Block)

– (void)handelWithBlock:(btnBlock)block{

if(block)    {        

objc_setAssociatedObject(self, &btnKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);   

 }  

  [self addTarget:selfaction:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside];

}

– (void)btnAction{   

btnBlock block = objc_getAssociatedObject(self, &btnKey);    

block();

}

@end

These two methods allow an object to be associated with another object, meaning that one object can keep a reference to another object and get that object. With this, you can implement the properties functionality. Policy can be set to the following values: