如何在Objective-C中使用运行时获取和设置属性值?在任何参数类型和返回类型
答案 0 :(得分:11)
首先,我们必须区分属性和ivars。如果访问者是明确编码的,或者该属性不是由ivar支持的,则称为“存储属性”。
一个。访问财产
由于属性只是访问器方法的声明,访问和获取属性意味着执行访问器方法。
属性对类的所有实例对象都是通用的。所以,首先得到它:
Class objectsClass = object_getClass( receiver );
然后你可以获得财产
objc_property_t property = class_getProperty( objectsClass, [propertyName cStringUsingEncoding:NSASCIIStringEnCoding] );
拥有该属性,您将获得setter和getter的标识符。
SEL getter;
const char* getterName = property_copyAttributeValue( property, "G" )
G
适用于getter,S
适用于设置者here。
if (getter==NULL)
{
getter = NSSelectorFromString( propertyName );
}
else
{
getter = sel_getUid( getterName );
}
使用setter它会有点复杂,因为你必须在属性的名称前加上set
,并使名字的第一个字符为大写。但是简单的字符串处理。
现在我们可以执行访问者了。这对于getter来说更复杂,因为你必须与返回类型不同:integral(id
,char
,unsigned int
,...),浮点(float
, double
,long double
)和结构。您将找到每种情况的函数,并应该转换结果。但是对于整数类型(包括指针),它看起来像这样:
id value = objc_msgSend( receiver, getter );
B中。获得Ivars价值
如果您想获取或设置ivar的值,则获取该属性的方法相同。在此之后,您阅读该属性的V
属性以获取ivar的名称。 (记住:@synthesize property = differentIvarName)。然后你得到了伊娃:
objc_ivar ivar = class_getInstanceVariable( objectsClass, ivarName );
得到它:
id value = object_getIvar( object, ivar );
如果是C类型,则必须采用不同的方式,例如
ptrdiff_t offset = ivar_getOffset( ivar );
double value = *((double*)(object+offset));
与setter模拟。
所有内容都在Safari中输入,无需重新检查文档。但它应该是一个深刻的指针。
BTW:类型编码描述为here。