Есть ли разница в производительности между этими двумя методами?
действительно, разница в производительности незначительна из-за того, что в подходе 2 у вас есть еще одно косвенное указание (то есть разыменование указателя, см. Также ниже); Итак, подход 1 сэкономит вам несколько тактов.
Второй подход совершенно бессмысленный?
подход 2 полезен, например, когда вы хотите выделить новый экземпляр типа Class2 и передать его вызывающей стороне через тот же аргумент; говорят:
- (bool)cloneObject:(Class2 **)var;
Вы передаете объект в; объект клонируется и возвращается в var; так как изменяется адрес самого объекта, вам нужно иметь указатель на указатель на объект, чтобы установить новый адрес; возвращаемое значение указывается только в том случае, если операция была выполнена правильно.
Конечно, в этом примере было бы более естественным сделать:
- (Class2)cloneObject:(Class2*)var;
Т.е. вы возвращаете указатель на вновь выделенный объект, но сценарий использования по-прежнему сохраняется.
Почему я могу использовать точечную запись в подходе 1, а использовать -> в подходе 2?
во втором случае вы должны использовать ->
, потому что вы не имеете дело с указателем на объект напрямую; вы имеете дело с указателем на указатель на объект; в таких случаях вам нужно, в первую очередь, «разыменовать» ваш указатель (т. е. применить оператор *), чтобы получить указатель на объект, а затем получить доступ к последнему, как вы сделали бы иначе; это можно написать так:
(*var).a
здесь var
- указатель на указатель на объект Class2
; *var
является результатом его разыменования, поэтому у вас есть указатель на объект Class2
; наконец, .a
- это синтаксис для доступа к свойству объекта. синтаксис:
var->a
- это просто «сокращение» для операций, описанных выше.