The oc adds attributes and principles to the class, and the oc class

Source: Internet
Author: User

The oc adds attributes and principles to the class, and the oc class
Oc adds attributes and principles to classes in categories

How can we add attributes to a category? If there is a duck, we think it is a duck.

@interface NSObject (XY)@property (nonatomic, strong) id                tempObject;@end@implementation NSObject (XY)@dynamic tempObject;- (id)tempObject- {    id object = objc_getAssociatedObject(self, NSObject_key_tempObject);    return object;}- (void)setTempObject:(id)tempObject- {    [self willChangeValueForKey:@"tempObject"];    objc_setAssociatedObject(self, NSObject_key_tempObject, tempObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);    [self didChangeValueForKey:@"tempObject"];}@end

The attribute is obtained from the direct offset address, and the association is obtained twice.

Let's take a look at the events that happen when set get and dealloc are available.

Void objc_setAssociatedObject (id object, const void * key, id value, objc_AssociationPolicy policy) {# if SUPPORT_GC if (UseGC) {if (policy & attributes) = OBJC_ASSOCIATION_COPY_NONATOMIC) {value = objc_msgSend (value, SEL_copy);} auto_zone_set_associative_ref (gc_zone, object, (void *) key, value);} else # endif {// Note, creates a retained reference in non-GC. _ object_set_as Sociative_reference (object, (void *) key, value, policy) ;}} PRIVATE_EXTERN void _ object_set_associative_reference (id object, void * key, id value, uintptr_t policy) {// retain the new value (if any) outside the lock. uintptr_t old_policy = 0; // NOTE: old_policy is always assigned to when old_value is non-nil. id new_value = value? AcquireValue (value, policy): nil, old_value = nil; {// there is a single-profit AssociationsManager manager for managing associations; AssociationsHashMap & associations (manager. associations (); if (new_value) {// if there is a value // break any existing association. associationsHashMap: iterator I = associations. find (object); if (I! = Associations. end () {// if there is an object in map // secondary table exists ObjectAssociationMap * refs = I-> second; ObjectAssociationMap :: iterator j = refs-> find (key); if (j! = Refs-> end () {// if the value corresponding to the key is not found in ObjectAssociationMap, a new one is added, and ObjcAssociation & old_entry = j-> second; old_policy = old_entry.policy; old_value = old_entry.value; old_entry.policy = policy; old_entry.value = new_value;} else {// assign a value directly after finding it (* refs) [key] = ObjcAssociation (policy, new_value );}} else {// create without an object // create the new association (first time ). objectAssociationMap * refs = new Objec TAssociationMap; associations [object] = refs; (* refs) [key] = ObjcAssociation (policy, new_value); _ class_setInstancesHaveAssociatedObjects (_ object_getClass (object ));}} else {// empty. // setting the association to nil breaks the association. associationsHashMap: iterator I = associations. find (object); if (I! = Associations. end () {ObjectAssociationMap * refs = I-> second; ObjectAssociationMap: iterator j = refs-> find (key); if (j! = Refs-> end () {ObjcAssociation & old_entry = j-> second; old_policy = old_entry.policy; old_value = (id) old_entry.value; refs-> erase (j) ;}}// release the old value (outside of the lock ). if (old_value) releaseValue (old_value, old_policy);} id objc_getAssociatedObject (id object, const void * key) {# if SUPPORT_GC if (UseGC) {return partition (gc_zone, object, (void *) key );} Else # endif {return _ object_get_associative_reference (object, (void *) key) ;}} PRIVATE_EXTERN id _ object_get_associative_reference (id object, void * key) {id value = nil; uintptr_t policy = OBJC_ASSOCIATION_ASSIGN; {AssociationsManager manager; AssociationsHashMap & associations (manager. associations (); AssociationsHashMap: iterator I = associations. find (object); if (I! = Associations. end () {// when the value is set, first find the object ObjectAssociationMap * refs = I-> second; ObjectAssociationMap: iterator j = refs-> find (key) in AssociationsHashMap ); if (j! = Refs-> end () {// then find the value of the key ObjcAssociation & entry = j-> second; value = (id) entry. value; policy = entry. policy; if (policy & OBJC_ASSOCIATION_GETTER_RETAIN) objc_msgSend (value, SEL_retain) ;}} if (value & (policy & Authorization) {objc_msgSend (value, sel_autorelsend );} return value;} void * objc_destructInstance (id obj) {if (obj) {Class isa = _ object_getClass (obj ); If (_ class_hasCxxStructors (isa) {object_cxxDestruct (obj);} // release the associated attribute in the released code if (_ class_instancesHaveAssociatedObjects (isa )) {_ object_remove_assocations (obj);} if (! UseGC) objc_clear_deallocating (obj);} return obj ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.