Objective-C Runtime — Handling Member Variables and Properties
Type Encoding As a supplement to the Runtime, the compiler encodes the return type and parameter types of each method into a string and associates it with the method's selector. This encoding scheme is also very useful in other contexts, so we can use the compiler directive to obtain it. Given a type, returns a string encoding for that type. These types can be primitive types such as or pointers, as well as structs, classes, and more. In fact, any type that can be used as an argument to can be used with . In the , the section lists all type encodings in Objective-C. Note that many of these types are the same as those used for archiving and distribution, but some cannot be used for archiving. Note: Objective-C does not support the type. returns , the same as . The type encoding of an array is enclosed in square brackets and includes the element count and element type. For example: Output: For other types, refer to ; they won't be covered in detail here. There are also some encoding types that won't return directly, but they can serve as type qualifiers for methods declared in protocols. See for details. For properties, there are also some special type encodings that indicate whether a property is read-only, copy, , etc. See for details. Member Variables and Properties Basic Data Types Ivar is the type representing an instance variable. It is actually a pointer to an struct, defined as: objcpropertyt is the type representing a declared Objective-C property. It is actually a pointer to an struct, defined as: objcpropertyattributet defines the attributes of a property. It is a struct defined as: Associated Objects Associated objects are a very practical Runtime feature that is easy to overlook. Associated objects are similar to member variables, but they are added at runtime. We typically put member variables () in the class's header file declaration, or after in the implementation file. But this has a limitation: we cannot add member variables in a category. If we try to add new member variables in a category, the compiler will report an error. We might try using global variables as a workaround, but those aren't s because they aren't tied to a single instance. So this approach is rarely used. Objective-C provides a solution: Associated Objects. Think of an associated object as an Objective-C object (like a dictionary) that is connected to a class instance via a given key. Since the interface is C-based, the key is a void pointer (). We also need to specify a memory management policy to tell the Runtime how to manage this object's memory. The policy is specified with one of the following values: When the host object is released, associated objects are handled according to the specified memory management policy. If the policy is , the associated object is not released when the host is released; if the policy is or , the associated object is released along with the host. You can even choose whether to use automatic retain/copy. This is very useful when writing multi-threaded code that accesses associated objects from multiple threads. Connecting an object to another requires just two lines of code: In this case, the object acquires a new associated object with the memory policy , meaning the association is automatically retained and will be released automatically when is released. Also, if we use the same key to associate a different object, the previous associated object will be automatically released — the old object is properly disposed of, and the new object takes its memory. We can use to remove an associated object, or use to set the associated object for a key to . Let's walk through a practical example of using associated objects. Suppose we want to dynamically attach a tap gesture to any and specify the action to perform upon tapping. We can associate a gesture object and an action block with our . This task has two parts. First, if needed, we create a gesture recognizer object and associate it along with the block. Here's the code: This code checks for an associated gesture recognizer object. If one doesn't exist, it creates one and establishes the association. It also associates the incoming block with the specified key. Note the memory management policy for the block association. The gesture recognizer needs a target and an action, so next we define the handler method: We need to check the gesture recognizer's state, since we only want to execute the action when the tap gesture is recognized. As you can see from the example above, associated objects are not complex to use. They let us dynamically augment a class's existing functionality. Feel free to apply this feature flexibly in real projects. Member Variable and Property Operation Functions Member Variables Member variable operations include the following functions: For the function: for instance variables of type or other object types, you can call and to access them directly without using the offset. Associated Objects Associated object operation functions include: Associated objects and related examples have already been discussed above. Properties** Property operation functions include: The function: the returned must be freed with after use. The function: the returned value must be freed with after use. Code: All code from this post can be found on my GitHub .