The difference between points and & # 8594; in objective c

I am trying to use as little memory as possible in my code. I tried two ways to send a custom class object to a method. I am not sure if there is a difference between the two approaches. Let's say I have 2 classes, Class1 and Class2 , each of which has its own class variables and methods.

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 a performance difference between the two methods? Is the second approach completely pointless? Why can I use dot notation in approach 1, but I need to use โ†’ in approach 2?

Thanks.

+4
source share
3 answers

Is there a performance difference between the two methods?

indeed, a slight difference in performance, due to the fact that in approach 2 you have another indirectness (i.e. dereferencing a pointer, see also below); therefore, approach 1 will save you a few measures.

Is the second approach completely pointless?

approach 2 is useful, for example, when you want to allocate a new instance of type Class2 and pass it back to the caller through the same argument; they say:

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

you are passing an object; the object is cloned and returned to var; since this is the address of the object itself that is changing, you need to have a pointer to a pointer to the object in order to set a new address; the return value indicates only the correct operation.

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

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

ie, you are returning a pointer to the selected object, but the use case is still preserved.

Why can I use dot notation in approach 1, but I need to use โ†’ in approach 2?

in the second case, you need to use -> because you do not have a direct pointer to the object; you are dealing with a pointer to a pointer to an object; what you need to do in such cases is, first of all, โ€œdereferencingโ€ your pointer (that is, using the * operator) to get a pointer to the object and then access the latter, as you would otherwise; it can be written like this:

  (*var).a 

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

 var->a 

is simply an "abbreviation" for the operations described above.

+4
source

In approach 1, you access a property named a . It looks good.

In approach 2, I am shocked that your code compiles. It is also useless to pass a pointer to class2Object . The only reason to ever pass pointers to objects is if the called method needs to update this parameter (for example, if it is an out parameter), which is not the case here. Passing a pointer to an object has absolutely no effect on memory usage. Objects are already considered pointers (so you write Class2 * ), so there is no overhead for copying such objects as you might see when passing around an object associated with the stack in C ++ (Obj-C has no concept of the -allocated objects stack , except for the blocks, which are a strange corner case that you have nothing to worry about).

So basically, just go with Approach 1 here.

+4
source

x->y in the C syntax is the same as (*x).y , so there is no difference in what it does, except for an extra (unnecessary) pointer and dereferencing, as others have said. But I would like to dwell on a more interesting related point.

You must understand that in

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

point is access to properties. (This cannot be access to the structure field, since var is a pointer.) This is exactly equivalent to int a = [var a]; (unless the recipient has explicitly set another method).

As with all method calls, it will go through a dynamic messaging engine. If you want to avoid minor overhead, you can access the variable directly.

If property a synthesized from an instance variable a (you could name something else, we will say a now) instead of accessing the variable through the property, you can instead declare it public (via @public , otherwise the instance variables will be protected by default), and then access it directly through -> :

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

(Note that this is different from what you have, because var is the pointer of the object itself, not the pointer to the pointer.)

However, public instance variables are generally considered bad and discouraged. With it, abstraction occurs in object-oriented programming. I bring it here for completeness, because technically it is the "fastest" method of accessing an instance variable.

+2
source

Source: https://habr.com/ru/post/1381175/


All Articles