Using Stored Properties in Swift Extensions
The main limitation of Swift Extensions is that stored properties cannot be added directly. However, there are alternative approaches to achieve this. Background Swift can add methods, structs, enums, or protocols to existing classes, and are one of the more commonly used Swift features. However, Swift does not natively support holding objects as stored properties in extensions. This post explains how to implement this using the existing APIs. Goal As an example, suppose we have an extension that needs a stored property to indicate whether the search bar is being used as a : At compile time, this causes an error: Clearly, Swift does not support stored properties in extensions. So we cannot use as a stored property directly. Solution Thinking back to associated objects in Objective-C, it's natural to consider using and to store objects associated with a specific key. This method requires two parameters (and requires four): 1. : The source object for the association. Typically is passed here. 2. : A pointer to the key for the associated object. 3. : The associated object. 4. : The policy for storing the object. Options include: - : Saves the object with a weak reference; retain count is not incremented. - : Strongly references the object non-atomically. - : Copies the object non-atomically. - : Strongly references the object atomically. - : Copies the object atomically. Note: Be careful when using the policy. The documentation says it uses a weak reference, but it is not exactly equivalent to — it is more like an reference. After the associated object is deallocated, the property still retains the deallocated address. Accessing it carelessly can result in a dangling pointer error. Here is the code: contains the associated keys. If there are multiple associated keys, use it like this: Since the parameter must be a pointer (), we use to get the address of . In most cases, the above code is sufficient. However, you can also refactor slightly using a generic method with a default value: With this, the code becomes: Complete code: