objective-c 用类别给类加属性以及原理

         objective-c 用类别给类加属性以及原理                     

objective-c 用类别给类加属性以及原理

转载请注明出处 uxyheaven csdn博客

如何在类别里给类加属性呢,有鸭子模样的我们就认为他是鸭子了.

@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



属性取变量是直接偏移地址得到,关联是取了2次map.

下面来看一下set get 还有dealloc时候发生的事情吧

void objc_setAssociatedObject(id object , const void *key, id value , objc_AssociationPolicy policy) { #if SUPPORT_GC if (UseGC) { if ((policy & OBJC_ASSOCIATION_COPY_NONATOMIC) == 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_associative_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; { // 有个管理关联的单利 AssociationsManager manager; AssociationsHashMap &associations(manager.associations()); if (new_value) { // 如果有值 // break any existing association. AssociationsHashMap::iterator i = associations.find( object ); if (i != associations.end()) { // 如果在map里有object的话 // secondary table exists ObjectAssociationMap *refs = i->second; ObjectAssociationMap::iterator j = refs->find(key); if (j != refs->end()) { // 如果在ObjectAssociationMap里没找到key对应的值就new一个,塞进去 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 { // 找到了就直接赋值 (*refs)[key] = ObjcAssociation(policy, new_value); } } else { // 没有object就创建 // create the new association (first time). ObjectAssociationMap *refs = new ObjectAssociationMap; associations[ object ] = refs; (*refs)[key] = ObjcAssociation(policy, new_value); _class_setInstancesHaveAssociatedObjects(_object_getClass( object )); } } else { // 没值就清空 // 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 auto_zone_get_associative_ref(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()) { // 取值的时候就在AssociationsHashMap里面先找到object ObjectAssociationMap *refs = i->second; ObjectAssociationMap::iterator j = refs->find(key); if (j != refs->end()) { // 然后找到的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 & OBJC_ASSOCIATION_GETTER_AUTORELEASE)) { objc_msgSend( value , SEL_autorelease); } return value ;} void *objc_destructInstance(id obj) { if (obj) { Class isa = _object_getClass(obj); if (_class_hasCxxStructors(isa)) { object_cxxDestruct(obj); } // 在释放的代码里,释放关联的属性 if (_class_instancesHaveAssociatedObjects(isa)) { _object_remove_assocations(obj); } if (!UseGC) objc_clear_deallocating(obj); } return obj;}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值