Search code examples
iosobjective-cmacosobjective-c-runtimeobjective-c-category

Difference between Associate Objects vs Properties vs Instance Variable


I have been digging into some Objective C runtime methods and was wondering what is the difference between Associate Objects and Properties.

I am most interested in their underlying implementation and pros/cons of dynamically using either and if one calls the other or if they are related to each other in any way.

These are the three runtime methods for adding each:

class_addProperty (Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount) 

vs

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

vs

class_addIvar(Class cls, const char *name, size_t size, uint8_t alignment, const char *types)

Solution

  • The immediate answer that comes to mind is that they are totally different, but I can see why someone may get mixed up.

    Properties

    In OOP, in general, a property is a method of an instance that provides the interface to read and/or write a particular data member.

    In Objective-C, the @syntheisze directive is used to direct the compiler to create or specify the methods to get and/or set some data member of a class instance. The methods themselves are often called "getters" and "setters."

    The important thing to keep in mind is that properties are glorified methods.

    Real variables, on the other hand, are physically given space (memory) to store their data. Let's say we have a class NSPerson:

    @interface NSPerson : NSObject
    
    @property (nonatomic, copy, readwrite) NSString *chosenName;
    @property (nonatomic, copy, readonly) NSString  *givenName;
    @property (nonatomic, copy, readonly) NSString  *fullName;
    
    @end
    
    @implementation NSPerson
    
    @synthesize chosenName = _chosenName, givenName = _givenName
    
    - (NSString *)fullName {
        return [NSString stringWithFormat:@"%@ %@", self.chosenName, self.givenName];
    }
    
    @end
    

    In this case, the @synthesize directive does the following:

    • Creates a variable named _chosenName
    • Creates a method - (NSString *)chosenName that returns _chosenName
    • Creates a method - (void)setChosenName:(NSString *)chosenName that sets _chosenName to the input
    • Does the same three things as above for givenName
    • Does nothing for fullName

    Now, fullName doesn't need its own memory because it has nothing to store. It also doesn't need a setter for the same reason. Because it is read only and we have explicitly provided an implementation of fullName, we're done - and fullName is a perfectly good property because it's a method that 1) takes no parameters in, and 2) spits the expected type out.

    Associated Objects

    Whereas properties are part of virtually every major OOP language, associated objects in the form that Apple provides are fairly unique to Objective-C.

    A better question would have been: what is the difference between a field (or instance variable) and an associated object?

    Both fields and associated objects hold data - unlike methods/properties, which just return data - and both can be tied to a particular instance.

    The way I think of associated objects is by way of analogy. You've probably dealt with some JSON before. A JSON object looks like this:

    var data = {
        balance: 15.04,
        mood: 'hungry',
        friends: [
             'larry',
             'momed',
             'zeus',
        ]
    }
    

    Now, each of the keys: balance for instance, is paired with a value. In this analogy, keys are the instance variables.

    Where might be the associated objects?

    var associated = {};
    var assc = associated[data] = {};  // the INSTANCE data is the KEY of the ASSOCIATIVE ARRAY
    assc.extrra = "peekaboo";
    

    I realize this is not a perfect analogy but I hope it is getting the point across that associated above is like the implementation of the Objective-C runtime that allows for associated objects - and that associated objects are variables not methods.

    Edit: Why associated objects?

    I ran out of gas but I wanted to mention that a major use of associated objects is to back properties in categories and extensions that cannot use traditional fields to store data. This is the usual connection between the two with respect to Objective-C.