Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is objc_setAssociatedObject() and in what cases should it be used?

In a project I have taken on, the original author has opted to use objc_setAssociatedObject() and I'm not 100% clear what it does or why they decided to use it.

I decided to look it up and, unfortunately, the docs aren't very descriptive about its purpose.

objc_setAssociatedObject
Sets an associated value for a given object using a given key and association policy.
void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy)
Parameters
object
The source object for the association.
key
The key for the association.
value
The value to associate with the key key for object. Pass nil to clear an existing association.
policy
The policy for the association. For possible values, see “Associative Object Behaviors.”

So what exactly does this function do and in what cases should it be used?


Edit after reading answers

So what is the point in the following code?

Device *device = [self.list objectAtIndex:[indexPath row]]; DeviceViewController *next = [[DeviceViewController alloc] initWithController:self.controller                                                                             device:device                                                                                item:self.rootVC.selectedItem];       objc_setAssociatedObject(device, &kDeviceControllerKey, next, OBJC_ASSOCIATION_RETAIN); 

What is the point in associating the device with the view controller if it's already an instance variable?

like image 567
Jasarien Avatar asked May 06 '11 09:05

Jasarien


People also ask

What is Objc_setassociatedobject?

Returns the value associated with a given object for a given key.

What is an associated object?

"Associated object" means that you possess an object taken from the desired destination within the last six months, such as a book from a wizard's library, bed linen from a royal suite, or a chunk of marble from a lich's secret tomb.


2 Answers

objc_setAssociatedObject adds a key value store to each Objective-C object. It lets you store additional state for the object, not reflected in its instance variables.

It's really convenient when you want to store things belonging to an object outside of the main implementation. One of the main use cases is in categories where you cannot add instance variables. Here you use objc_setAssociatedObject to attach your additional variables to the self object.

When using the right association policy your objects will be released when the main object is deallocated.

like image 70
Nikolai Ruhe Avatar answered Sep 21 '22 13:09

Nikolai Ruhe


From the reference documents on Objective-C Runtime Reference:

You use the Objective-C runtime function objc_setAssociatedObject to make an association between one object and another. The function takes four parameters: the source object, a key, the value, and an association policy constant. The key is a void pointer.

  • The key for each association must be unique. A typical pattern is to use a static variable.
  • The policy specifies whether the associated object is assigned,
    retained, or copied, and whether the
    association is be made atomically or
    non-atomically. This pattern is
    similar to that of the attributes of
    a declared property (see “Property
    Declaration Attributes”). You specify the policy for the relationship using a constant (see
    objc_AssociationPolicy and
    Associative Object Behaviors).

Establishing an association between an array and a string

static char overviewKey;    NSArray *array =      [[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", nil];  // For the purposes of illustration, use initWithFormat: to ensure  // the string can be deallocated  NSString *overview =      [[NSString alloc] initWithFormat:@"%@", @"First three numbers"];    objc_setAssociatedObject (      array,      &overviewKey,      overview,      OBJC_ASSOCIATION_RETAIN  );    [overview release];  // (1) overview valid  [array release];  // (2) overview invalid 

At point 1, the string overview is still valid because the OBJC_ASSOCIATION_RETAIN policy specifies that the array retains the associated object. When the array is deallocated, however (at point 2), overview is released and so in this case also deallocated. If you try to, for example, log the value of overview, you generate a runtime exception.

like image 42
visakh7 Avatar answered Sep 25 '22 13:09

visakh7