如何在 Objective-C 中使用运行时获取和设置属性值 [英] how to get and set a property value with runtime in Objective-C

查看:76
本文介绍了如何在 Objective-C 中使用运行时获取和设置属性值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

how to get and set a property value with runtime in Objective-C? in any argument type and return type

推荐答案

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

First we have to differentiate between properties and ivars. If an accessor is coded explicitly or if the property is not ivar-backed, it is called a "stored property".

A.访问属性

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

Since a property is simply the declaration of accessor methods, accessing and getting properties means to execute a accessor method.

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

A property is universal to all instance objects of a class. So, first get it:

Class objectsClass = object_getClass( receiver );

然后你就可以得到财产

objc_property_t property = class_getProperty( objectsClass, [propertyName cStringUsingEncoding:NSASCIIStringEnCoding] );

有了属性,你就可以得到 setter 和 getter 的标识符.

Having the property, you get the identifiers of the setter and getter.

SEL getter;
const char* getterName = property_copyAttributeValue( property, "G" ) 

G 用于 getter,S 用于 setter,如 此处.

G is for getter, S is for setter as described here.

IIRC,如果访问器没有显式设置(setter=..., getter=...),您将得到 nil,因此您必须按照命名约定获取属性名称:

IIRC, you get nil, if the accessor is not set explicitly (setter=…, getter=…), so you have to take the properties name following the naming conventions:

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

使用 setter 会稍微复杂一些,因为您必须在属性名称前加上 set 前缀,并使名称的第一个字符大写.而是简单的字符串处理.

With a setter it is a bit more complicated, because you have to prefix the property's name with set and make the first character of the name uppercased. But simple string processing.

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

Now we can execute the accessor. This is for getters more complicated, because you have to differ from the return types: integral (id, char, unsigned int, …), floating-point (float, double, long double) and structures. You will find a function for each case and should cast the result. However for integral types (including pointers) it looks like this:

id value = objc_msgSend( receiver, getter );

B.获取 Ivars 值

B. Getting the Ivars Value

如果要获取或设置ivar的值,获取属性的方法也是一样的.在此之后,您读取属性的 V 属性以获取 ivar 的名称.(记住:@synthesize property=differentIvarName).然后你得到了 ivar:

If you want to get or set the value of the ivar, it is the same way to get the property. After this you read the V attribute of the property to get the ivar's name. (Remember: @synthesize property=differentIvarName). Then you get the ivar:

objc_ivar ivar = class_getInstanceVariable( objectsClass, ivarName );

得到它:

id value = object_getIvar( object, ivar );

如果是C类型,就得另辟蹊径,例如

If it is a C type, you have to go a different way, for example

ptrdiff_t offset = ivar_getOffset( ivar );
double value = *((double*)(object+offset));

类似于二传手.

所有内容均在 Safari 中输入,无需重新检查文档.但是它应该是一个深指针.

All is typed in Safari without rechecking the docs. However it should be a deep pointer.

顺便说一句:类型编码描述 这里.

BTW: The type encoding are described here.

这篇关于如何在 Objective-C 中使用运行时获取和设置属性值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆