在运行时从类外部访问Objective-C ivar

在运行时从类外部访问Objective-C ivar,objective-c,c,objective-c-runtime,Objective C,C,Objective C Runtime,我知道这个想法完全破坏了封装,但假设我有以下类扩展: @interface MyClass () { int reallyImportantIvar; } // ... @end 通常情况下,该类在Objective-C层中的行为应该是发送和接收消息,等等。但是有一个“公共”子例程,我需要最好的性能和非常低的延迟,所以我更喜欢使用C方法。当然,如果我这样做了,我就不能再访问真正重要的Tivar,这是我的性能关键任务的关键 看来我有两个选择: 将实例变量改为静态变量。 通过Objecti

我知道这个想法完全破坏了封装,但假设我有以下类扩展:

@interface MyClass () {
    int reallyImportantIvar;
}
// ...
@end
通常情况下,该类在Objective-C层中的行为应该是发送和接收消息,等等。但是有一个“公共”子例程,我需要最好的性能和非常低的延迟,所以我更喜欢使用C方法。当然,如果我这样做了,我就不能再访问真正重要的Tivar,这是我的性能关键任务的关键

看来我有两个选择:

将实例变量改为静态变量。 通过Objective-C运行时直接访问实例变量。
我的问题是:选项2是否可能,如果可能,其开销是多少?例如,我是否仍在使用On算法查找类的实例变量?

Objective-C运行时包含object\u getInstanceVariable函数。我相信这就是你想要的。我没有详细检查过,但我认为这种访问方式与普通访问方式没有什么大的区别。

实际上,如果C函数的定义在类的@implementation块中,那么它可以通过常用的object->someIvar表示法访问该类上的私有IVAR。因此,虽然您可以使用运行时访问它,但我认为您不需要这样做。只需在所讨论的类的@implementation块中实现该函数,就可以了。

另一种选择是将ivar声明为@package或@public。然后,类实现之外的代码(可以包括该类扩展)可以使用ivar


@public允许任何代码这样做@包将作用域限制为与类的实现相同的二进制文件,这通常适用于编写共享库。

实例变量查找非常快。其他人会有更好的答案,但在您用探查器证明某些性能问题之前,我怀疑你选错了树。既然object_getInstanceVariable取了实例变量的名称,这难道不会比给编译器一个表达式foo->reallymortantivar慢吗?或者该表达式基本上编译为object_getInstanceVariable?object_getInstanceVariable速度不快。如果想要快速,应该使用class_getInstanceVariable和ivar_getOffset并保存结果。或者在@implementation中编写C函数,如另一个答案中所述。这虽然鲜为人知,但影响很大。只是不要无缘无故地到处做这件事。