如何在Objective-C中使用运行时获取和设置属性值

时间:2015-04-15 04:04:40

标签: ios objective-c runtime

如何在Objective-C中使用运行时获取和设置属性值?在任何参数类型和返回类型

1 个答案:

答案 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

IIRC,如果没有明确设置访问者(setter = ...,getter = ...),你得到nil,所以你必须按照命名约定取属性名称:

if (getter==NULL)
{
  getter = NSSelectorFromString( propertyName );
}
else
{
  getter = sel_getUid( getterName );
}

使用setter它会有点复杂,因为你必须在属性的名称前加上set,并使名字的第一个字符为大写。但是简单的字符串处理。

现在我们可以执行访问者了。这对于getter来说更复杂,因为你必须与返回类型不同:integral(idcharunsigned int,...),浮点​​(floatdoublelong 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