سؤال

I can define a class with a property to access my ivars from outside of the class.

I can also just use the myInst->ivar syntax to access in a C-struct fashion.

In C++, I would go with accessors, but in objective-c there are some cases where I may want direct access. The messaging system incurs a large performance hit with the accessor that matters in some contexts, since the message isn't inlined like it can be with C++ methods.

For example in a class that has an ivar called scalar and a property defined on it. scalar is a simple float value:

-(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];
   }
}

If i change [myinst scalar] to myinst->scalar, the method will run a lot faster, since using calls with the accessor would take up most of the CPU in this loop.

As with C++ I understand direct ivar access is in general discouraged, but in this context, when speed matters, is it acceptable? If not, is there a more preferred method that still uses an objective-c class?

هل كانت مفيدة؟

المحلول

Many things become acceptable when it has a significant impact on performance, but in the example you're giving, there seem to be much better solutions.

First, why doesn't [myinst computeNextScalar:i] return the new scalar? If you did that, you wouldn't need to fetch it and everything would be much faster.

Can't the work be moved into myinst? I mean, can't you create something like:

result = [myinst totalOverArray:array];

If reallyBigX is really big, then you should consider the Accelerate.framework here. It can significantly improve performance on the kind of operation you seem to be doing. (You have to do performance testing with the Accelerate framework. It can be substantially slower for some operations, but this one might be faster.)

Finally, consider the Objective-C get... pattern. It looks like this:

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);

BTW, the above is definitely a candidate for vDSP_dotpr(), though you should performance-test it. In many cases the simple loop is faster than an equivalent vDSP call when stride=1 (since you can use a simple increment rather than += stride).

نصائح أخرى

Yes, it is acceptable: the @public, @private, etc. access modifiers were introduced in part to support designs where accessing ivars from outside the class is required. You should avoid writing directly to ivars, though.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top