Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference Between Dot Notation and -> in Objective C

I'm trying to use as little memory as possible in my code. I've tried two ways of sending a custom class object to a method. I'm not sure if there is any difference between these two approaches. Say I have 2 classes, Class1 and Class2 each with their own class variables and methods of course.

All code is written in Class1

Approach 1:

Class2 *class2Object = [[Class2 alloc] init];

[self doSomething: class2Object];

[class2Object release];

-(void) doSomething: (Class2 *) var {
int a = var.a;
}

Approach 2:

Class2 *class2Object = [[Class2 alloc] init];

[self doSomething: &class2Object];

[class2Object release];

-(void) doSomething: (Class2 **) var {
int a = var->a;
}

Is there any performance difference between these two methods? Is the second approach completely pointless? Why is it that I can use the dot notation in Approach 1, but have to use -> in Approach 2?

Thanks.

like image 303
Kevin_TA Avatar asked Dec 27 '22 11:12

Kevin_TA


2 Answers

Is there any performance difference between these two methods?

indeed, there is a negligible difference in performance, due to the fact that in approach 2 you have one more indirection (i.e., pointer dereferencing, see also below); so, approach 1 will save you a few clock cycles.

Is the second approach completely pointless?

approach 2 is useful,e.g., when you would like to allocate a new instance of type Class2 and pass it back to the caller through the same argument; say:

 - (bool)cloneObject:(Class2 **)var;

you pass an object in; the object is cloned and returned in var; since it is the address of the object itself which changes, you need to have a pointer to the pointer to the object in order to set the new address; the return value only states if the operation was executed correctly.

Of course, in this example, it would be more natural doing:

     - (Class2)cloneObject:(Class2*)var;

i.e., you return the pointer to the object newly allocated, but the use case still holds.

Why is it that I can use the dot notation in Approach 1, but have to use -> in Approach 2?

in the second case you have to use -> because you are not dealing with a pointer to an object directly; you are dealing with a pointer to a pointer to an object; what you need do in such cases is, first of all, "dereferencing" your pointer (i.e., applying operator *) in order to get a pointer to the object, then accessing the latter as you would do otherwise; this could be written like:

 (*var).a

here, var is a pointer to a pointer to an object of Class2; *var is the result of dereferencing it, so you have a pointer to an object of Class2; finally, .a is the syntax to access an object property. the syntax:

var->a

is simply a "shorthand" for the operations described above.

like image 56
sergio Avatar answered Dec 30 '22 09:12

sergio


In Approach 1, you're accessing a property named a. This looks fine.

In Approach 2, I'm shocked that your code compiles. It's also utterly useless to be passing a pointer to class2Object. The only reason to ever pass pointers to objects is if the called method needs to update that parameter (e.g. if it's an out-parameter), which is not the case here. Passing a pointer to an object has absolutely no bearing on memory usage. Objects are already held as pointers (which is why you write Class2 *), so there's no overhead of copying objects like you might see when passing around a stack-allocated object in C++ (Obj-C doesn't have the concept of stack-allocated objects, except for blocks which is a weird corner case that you don't have to worry about).

So basically, just go with Approach 1 here.

like image 40
Lily Ballard Avatar answered Dec 30 '22 11:12

Lily Ballard