2

我可以定义一个具有属性的类,以从类外部访问我的 ivars。

我也可以只使用 myInst->ivar 语法以 C-struct 方式访问。

在 C++ 中,我会使用访问器,但在 Objective-c 中,在某些情况下我可能需要直接访问。消息传递系统对在某些上下文中很重要的访问器造成很大的性能损失,因为消息不像 C++ 方法那样内联。

例如,在一个类中,它有一个名为 scalar 的 ivar 和一个在其上定义的属性。标量是一个简单的浮点值:

-(void) doWorkWithMyClass:(MyClass*)myinst
{
   // array and other locals declaration omitted 
   for (int i = 0; i < reallyBigX; i++) {
      result += [myinst scalar] * array[i];
      [myinst computeNextScalar:i];
   }
}

如果我将 [myinst scalar] 更改为 myinst->scalar,该方法将运行得更快,因为在此循环中使用访问器调用会占用大部分 CPU。

与 C++ 一样,我理解通常不鼓励直接访问 ivar,但在这种情况下,当速度很重要时,它可以接受吗?如果没有,是否有更首选的方法仍然使用objective-c 类?

4

2 回答 2

6

当它对性能产生重大影响时,许多事情变得可以接受,但是在您给出的示例中,似乎有更好的解决方案。

首先,为什么不[myinst computeNextScalar:i]返回新的标量?如果你这样做了,你就不需要获取它,一切都会快得多。

作品不能搬进去myinst吗?我的意思是,你不能创建类似的东西:

result = [myinst totalOverArray:array];

如果reallyBigX真的很大,那么你应该在这里考虑 Accelerate.framework。它可以显着提高您似乎正在执行的操作的性能。(您必须使用 Accelerate 框架进行性能测试。对于某些操作,它可能会慢很多,但这个可能会更快。)

最后,考虑一下 Objective-Cget...模式。它看起来像这样:

int *scalars = calloc(reallyBigX, sizeof(int));
[myinst getScalars:scalars range:NSMakeRange(0, reallyBigX)];
for (int i = 0; i < reallyBigX; i++) {
   result += scalars[i] * array[i];
}
free(scalars);

顺便说一句,以上绝对是 的候选者vDSP_dotpr(),尽管您应该对其进行性能测试。在许多情况下,当 stride=1 时,简单循环比等效vDSP调用更快(因为您可以使用简单的增量而不是+= stride)。

于 2012-02-20T00:42:24.237 回答
1

是的,这是可以接受的:引入@public,@private等访问修饰符部分是为了支持需要从类外部访问 ivars 的设计。不过,您应该避免直接写入 ivars。

于 2012-02-19T23:45:42.053 回答