ios動態新增屬性的幾種方法

2021-09-07 07:22:32 字數 3208 閱讀 5451

在ios執行過程中,有幾種方式能夠動態的新增屬性。

1-通過runtime動態關聯物件

主要用到了objc_setassociatedobject,objc_getassociatedobject以及objc_removeassociatedobjects

[objc]view plain

copy

//在目標target上新增關聯物件,屬性名propertyname(也能用來新增block),值value  

+ (void)addassociatedwithtarget:(id)targetwithpropertyname:(nsstring *)propertynamewithvalue:(id)value   

}  //獲取目標target的指定關聯物件值  

+ (id)getassociatedvaluewithtarget:(id)targetwithpropertyname:(nsstring *)propertyname   

優點:這種方式能夠使我們快速的在乙個已有的class內部新增乙個動態屬性或block塊。

缺點:不能像遍歷屬性一樣的遍歷我們所有關聯物件,且不能移除制定的關聯物件,只能通過removeassociatedobjects方法移除所有關聯物件。

2-通過runtime動態新增ivar

主要用到objc_allocateclasspair,class_addivar,objc_registerclasspair

[objc]view plain

copy

//在目標target上新增屬性(已經存在的類不支援,可跳進去看注釋),屬性名propertyname,值value  

+ (void)addivarwithtarget:(id)targetwithpropertyname:(nsstring *)propertynamewithvalue:(id)value   

}  //獲取目標target的指定屬性值  

+ (id)getivarvaluewithtarget:(id)targetwithpropertyname:(nsstring *)propertyname  else   

}  

優點:動態新增ivar我們能夠通過遍歷ivar得到我們所新增的屬性。

缺點:不能在已存在的class中新增ivar,所有說必須通過objc_allocateclasspair動態建立乙個class,才能呼叫class_addivar建立ivar,最後通過objc_registerclasspair註冊class。

3-通過runtime動態新增property

主要用到class_addproperty,class_addmethod,class_replaceproperty,class_getinstancevariable

[objc]view plain

copy

//在目標target上新增屬性,屬性名propertyname,值value  

+ (void)addpropertywithtarget:(id)targetwithpropertyname:(nsstring *)propertynamewithvalue:(id)value   

/* objc_property_attribute_t type = ; 

objc_property_attribute_t ownership = ; // c = copy 

objc_property_attribute_t backingivar  = ; 

objc_property_attribute_t attrs = ; 

class_addproperty([someclass class], "name", attrs, 3); 

*/  

//objc_property_attribute_t所代表的意思可以呼叫getpropertynamelist列印,大概就能猜出  

objc_property_attribute_t type = ;  

objc_property_attribute_t ownership = ;  

objc_property_attribute_t backingivar  = ;  

objc_property_attribute_t attrs = ;  

if (class_addproperty([targetclass], [propertynameutf8string], attrs, 3))  else   

}  id getter(id self1, sel _cmd1)   

void setter(id self1, sel _cmd1, id newvalue)   

[dictcustomerpropertysetobject:newvalueforkey:key];  

}  + (id)getpropertyvaluewithtarget:(id)targetwithpropertyname:(nsstring *)propertyname   

ivar = class_getinstancevariable([targetclass], "_dictcustomerproperty");  //basicsviewcontroller裡面有個_dictcustomerproperty屬性  

nsmutabledictionary *dict = object_getivar(target, ivar);  

if (dict && [dictobjectforkey:propertyname])  else   

}  

優點:這種方法能夠在已有的類中新增property,且能夠遍歷到動態新增的屬性。

缺點:比較麻煩,getter和setter需要自己寫,且值也需要自己儲存,如上面的**,我是把setter中的值儲存到了_dictcustomerproperty裡面,在getter中再從_dictcustomerproperty讀出值。

4-通過setvalue:forundefinedkey動態新增鍵值

這種方法優點類似property,需要重寫setvalue:forundefinedkey和valueforundefinedkey:,存值方式也一樣,需要借助乙個其它物件。由於這種方式沒通過runtime,所以也比較容易理解。在此就不舉例了。

JS動態新增事件的幾種方法

js動態新增事件的幾種方法 下面的div2是乙個div 第一種 div2.setattribute onmouseover this.style.backgroundcolor blue div2.setattribute onmouseout this.style.backgroundcolor ...

iOS動態新增屬性

之前一篇文章 ios關聯物件 詳細介紹了如何通過關聯物件新增屬性,本篇文章將介紹如何通過runtime的class addproperty或class addivar動態新增屬性,並且帶領大家看看這兩個方法底層是如何實現的。對於已經存在的類我們用class addproperty方法來新增屬性,而對...

iOS 延遲執行的幾種方法

void viewdidload void delaymenthod 注 此方法是一種非阻塞的執行方式,可以傳遞引數,未找到取消執行的方法。void viewdidload void delaymenthod 注 此方法是一種非阻塞的執行方式,可以傳遞引數,timer invalidate 取消執行...