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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With