Подтвердить что ты не робот

Почему `&` (амперсанд) помещается перед некоторыми параметрами метода?

Интересно, почему перед NSError, например, ниже, мы помещаем: &error, а не error?

например.

NSArray *result = [managedObjectContext executeFetchRequest:fetchRequest error:&error];

Надеюсь, вы сможете объяснить, также это всегда так или только в определенных ситуациях это необходимо? Спасибо.

4b9b3361

Ответ 1

Вам нужно взять адрес error, потому что функция должна его изменить. error передается указателем, поэтому вам нужен оператор "принять адрес" &.

C и Objective-C передать параметры по значению. Если вы передадите error без амперсанда, а метод, который вы вызываете, изменяет его, ваша функция, которая сделала вызов, не увидит никаких изменений, потому что метод будет работать с его локальной копией NSError*.

Вы знаете, что вам нужен амперсанд перед соответствующим параметром, если вы посмотрите на подпись метода и посмотрите ** там:

- (NSArray *)executeFetchRequest:(NSFetchRequest *)request error:(NSError **)error
                                            //   ^ one                    ^^ two

Ответ 2

Тип параметра error - (NSError **), то есть указатель на указатель на NSError. Переменная error, которую вы используете в качестве аргумента, вероятно, объявлена ​​как NSError *, поэтому для правильного соответствия типов вам необходимо использовать адрес оператора, чтобы получить указатель на указатель (&error), Причина, по которой методу требуется указатель на указатель в первую очередь, заключается в том, что он может изменить значение error и получить это новое значение для вас, вызывающего метода.

Ответ 3

По сути, корень проблемы - это взлом за то, что он хочет вернуть второй (необязательный) объект.

Как мы можем это сделать, поскольку мы можем только вернуть одно? Ну, мы могли бы вернуть какой-то кортеж (return_value, error), но это немного громоздко. У нас может быть столько параметров, сколько нам нравится, можем ли мы что-то сделать с этими...

Таким образом, методы/функции не могут изменять свои параметры (точнее, они работают с копией, поэтому любые модификации, которые они делают, являются локальными). То есть (concurrency оставляет в стороне) значение fetchRequest, прежде чем сообщение в вашем вопросе будет равно значению fetchRequest. Обратите внимание, что объект, на который указывает fetchRequest, может измениться, но значение fetchRequest не будет.

Это немного связывает нас. Кроме того, подождите, мы знаем, что можем с радостью принять значение параметра и изменить то, на что оно указывает! Если вы посмотрите на объявление для executeFetchRequest:error:, вы увидите, что он принимает значение NSError**. Это "указатель на указатель на NSError". Итак, мы можем инициализировать пустой/оборванный NSError*, найти его адрес (с помощью унарного & оператора) и передать это in. Затем этот метод может быть привязан к NSError*, указанному этим.

Voila, у нас есть дополнительные дополнительные возвращаемые значения.