The Runtime association_policy provides only assign but not weak. Assign is the closest modifier to weak compared to the other modifiers, so we modify assign to do the job of weak.

In the case of holding objects, the biggest difference between weak and assign lies in the last item, how to set a reference to nil after the object is destroyed. The weak property is automatically set to nil after the destruction of the weak object. The best advantage of this is that subsequent messages are not damaged by the destruction of the object. The assign property does not automatically become nil, forming a wild pointer, so if the object is not destroyed after that, it is likely to send a message to the wild pointer, causing crash. Officially, it’s recommended to use weak instead of assign if you don’t want to increase the reference counter that holds the object, as you can see from the header provided by Apple — all delegate modifiers are weak.

Associative objects are an important skill in the Runtime, and I assume that you already know how associative objects operate, and that you can use associative objects to add attributes to existing classes. If you don’t know enough about Runtime, check out some articles on the Web, or check out my Runtime series on GitHub. The most important c functions for associative objects are the following:

void objc_setAssociatedObject(id obj, const void *key, id value, objc_AssociationPolicy policy); id objc_getAssociatedObject(id obj, const void *key);

/** This is a new CategoryProperty of an existing class in the.h file */ @property (nonatomic, strong) NSObject * CategoryProperty;

/** This is an implementation of the set method in the.m file */

  • (void)setCategoryProperty:(id)categoryProperty { objc_setAssociatedObject(self, “categoryProperty”, categoryProperty, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

} /** This is an implementation of the get method in the.m file */

  • (id)categoryProperty { return objc_getAssociatedObject(self, “categoryProperty”);

}

This association object can be encapsulated as a classification of NSObject for later manipulation. / * *

  • This is the class that NSObject adds based on Runtime, and you can call this class directly later if you want to add attributes to an existing class

**/ @implementation NSObject (Association)

/** The set method of all attributes to be added can be called to implement */

  • (void)setAssociatedObject:(id)obj forKey:(NSString *)key { objc_setAssociatedObject(self, key.UTF8String, obj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

} /** All get methods for attributes to be added can call this method to implement */

  • (id)associatedObjectForKey:(NSString *)key { return objc_getAssociatedObject(self, key.UTF8String);

} @end

*/ @property (nonatomic, strong) NSObject *categoryProperty; */ @property (nonatomic, strong) NSObject *categoryProperty;

/** An implementation of the set method that adds attributes using the above classification */

  • (void)setCategoryProperty:(id)categoryProperty { [self setAssociatedObject:categoryProperty forKey:@”categoryProperty”];

}

/** An implementation of the get method that adds attributes using the above classification */

  • (id)categoryProperty { return [self associatedObjectForKey:@”categoryProperty”];

}

In an NSDictionary, both names can be used as keys to fetch the same object, so we can consider storing const char * as value and NSString * as key in an NSDictionary, Const char * is a basic data type and cannot be stored in an OC container class, so we need to wrap it with an NSValue. /** this is a NSString => NSValue< const char * > */ static NSMutableDictionary *keyBuffer;

@implementation NSObject (Association)

  • (void)load { keyBuffer = [NSMutableDictionary dictionary]; // Create a dictionary

}

/ * *

  • Set method to be called by the set method of the property when the property is added later
  • @param Object The object to associate with, that is, the new property value to set
  • @param Key Attribute name. The name of the new attribute is passed in

* * /

  • (void)setAssociatedObject:(id)object forKey:(NSString *)key { const char *cKey = [keyBuffer[key] pointerValue]; // Obtain key if (cKey == NULL) {// Create an cKey = key.utf8String; keyBuffer[key] = [NSValue valueWithPointer:cKey]; } objc_setAssociatedObject(self, cKey, object, OBJC_ASSOCIATION_RETAIN);

}

/ * *

  • Get method to be called by the get method of the property when the property is added later
  • @param Key Attribute name

* /

  • (id)associatedObjectForKey:(NSString *)key { const char *cKey = [keyBuffer[key] pointerValue]; if (cKey == NULL) { return nil; } else { return objc_getAssociatedObject(self, cKey); }

}

@end

Arunachal pradesh

  • Policies related to associative references.
  • These are options to objc_setAssociatedObject()

/ typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) { OBJC_ASSOCIATION_ASSIGN = 0, /* assign / OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /* retain, nonatomic / OBJC_ASSOCIATION_COPY_NONATOMIC = 3, /* copy, nonatomic / OBJC_ASSOCIATION_RETAIN = 01401, /* retain, atmoic / OBJC_ASSOCIATION_COPY = 01403 /* copy, atomic */ };