我可以定义一个具有属性的类,以便从类外部访问我的ivars。
我也可以使用myInst-> ivar语法以C-struct方式访问。
在C ++中,我会使用访问器,但在objective-c中,有些情况下我可能需要直接访问。消息传递系统在某些上下文中对访问器造成了很大的性能损失,因为消息没有像C ++方法那样内联。
例如,在具有名为标量的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标量]更改为myinst-&gt;标量,则该方法将运行得更快,因为使用访问器调用会占用此循环中的大部分CPU。
与C ++一样,我理解一般不鼓励直接进行ivar访问,但在这种情况下,当速度很重要时,它是否可以接受?如果没有,是否有更优选的方法仍使用objective-c类?
答案 0 :(得分:6)
当它对性能产生重大影响时,很多事情都会被接受,但在你给出的例子中,似乎有更好的解决方案。
首先,为什么[myinst computeNextScalar:i]
没有返回新的标量?如果你这样做,你就不需要获取它,一切都会快得多。
无法将作品移至myinst
?我的意思是,你不能创造类似的东西:
result = [myinst totalOverArray:array];
如果reallyBigX
真的很大,那么你应该在这里考虑Accelerate.framework。它可以显着提高您似乎正在进行的操作的性能。 (你必须使用Accelerate框架进行性能测试。对于某些操作来说,它可能会慢得多,但这个操作可能会更快。)
最后,考虑Objective-C get...
模式。它看起来像这样:
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
)。
答案 1 :(得分:1)
是的,可以接受:部分引入了@public
,@private
等访问修饰符,以支持需要从类外部访问ivars的设计。但是,你应该避免直接写入ivars。