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

zix*_*xun -1 runtime objective-c ios

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

Ami*_*wad 12

首先,我们必须区分属性和ivars.如果访问者被明确编码或者该属性不是由ivar支持的,则称为"存储属性".

A.访问财产

由于属性只是访问器方法的声明,因此访问和获取属性意味着执行访问器方法.

属性对于类的所有实例对象是通用的.所以,首先得到它:

Class objectsClass = object_getClass( receiver );
Run Code Online (Sandbox Code Playgroud)

然后你就可以得到这家酒店

objc_property_t property = class_getProperty( objectsClass, [propertyName cStringUsingEncoding:NSASCIIStringEnCoding] );
Run Code Online (Sandbox Code Playgroud)

拥有该属性,您将获得setter和getter的标识符.

SEL getter;
const char* getterName = property_copyAttributeValue( property, "G" ) 
Run Code Online (Sandbox Code Playgroud)

G适用于吸气剂,S适用于此处所述的定位器.

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

if (getter==NULL)
{
  getter = NSSelectorFromString( propertyName );
}
else
{
  getter = sel_getUid( getterName );
}
Run Code Online (Sandbox Code Playgroud)

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

现在我们可以执行访问器了.这是干将更加复杂,因为你不得不从返回类型不同:积分(id,char,unsigned int,...),浮点(float,double,long double)和结构.您将找到每种情况的函数,并应该转换结果.但是对于整数类型(包括指针),它看起来像这样:

id value = objc_msgSend( receiver, getter );
Run Code Online (Sandbox Code Playgroud)

B.获得Ivars价值

如果要获取或设置ivar的值,则获取属性的方式相同.在此之后,您将读取V属性的属性以获取ivar的名称.(记住:@synthesize property = differentIvarName).然后你得到了伊娃:

objc_ivar ivar = class_getInstanceVariable( objectsClass, ivarName );
Run Code Online (Sandbox Code Playgroud)

得到它:

id value = object_getIvar( object, ivar );
Run Code Online (Sandbox Code Playgroud)

例如,如果它是C类型,则必须采用不同的方式

ptrdiff_t offset = ivar_getOffset( ivar );
double value = *((double*)(object+offset));
Run Code Online (Sandbox Code Playgroud)

与setter模拟.

所有都是在Safari中键入而无需重新检查文档.但它应该是一个深刻的指针.

BTW:此处描述类型编码.