为什么' & '(&)放在一些方法参数前面?

时间:2020-12-01 00:18:33

I'ver wondered, why is it that in front of an NSError, such as below, do we put: &error and not error?

我很好奇,为什么在一个NSError面前,比如下面,我们要输入:&error而不是error?

E.g.

如。

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

Hope you can explain, also is this always the way or only in certain situations this is needed? Thanks.

希望你能解释一下,在某些情况下,这也是需要的吗?谢谢。

3 个解决方案

#1


57  

You need to take the address of error because the function needs to modify it. error is passed by pointer, so you need the "take address" operator & for it.

您需要获取错误地址,因为函数需要修改它。错误是通过指针传递的,所以需要使用“take address”操作符。

C and Objective-C pass parameters by value. If you pass error without an ampersand and the method that you call modifies it, your function that made the call would not see any changes, because the method would operate on its local copy of NSError*.

C和Objective-C按值传递参数。如果您传递的错误没有符号,并且您调用的方法修改了它,那么进行调用的函数将不会看到任何更改,因为该方法将对其NSError*的本地副本进行操作。

You know that you need an ampersand in front of the corresponding parameter if you look at the signature of the method and see ** there:

如果您查看方法的签名并在那里看到**,您就知道需要在相应的参数前面加上一个&号:

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

#2


7  

The error parameter's type is (NSError **), that is a pointer to a pointer to an NSError. The error variable that you use as the argument is probably declared as NSError *, so in order to get the types to match properly, you have to use the address of operator to get a pointer to a pointer (&error). The reason the method needs a pointer to a pointer in the first place is so that it can modify the value of error and have that new value be available to you, the caller of the method.

错误参数的类型是(NSError **),它是指向NSError的指针。作为参数使用的错误变量可能被声明为NSError *,因此为了使类型正确匹配,您必须使用操作符的地址来获取指向指针的指针(和错误)。这个方法首先需要一个指针指向一个指针,这样它就可以修改错误的值,并让这个方法的调用者可以获得新的值。

#3


6  

Essentially, the root of the issue is a hack for wanting to return a second (optional) object.

本质上,这个问题的根源是想要返回第二个(可选)对象的hack。

How can we do this, as we can only return one thing? Well, we could return some sort of (return_value, error) tuple, but that's a bit unwieldy. We can have as many parameters as we like though, can we do something with those...

我们怎么做呢,因为我们只能返回一件东西?我们可以返回某种(return_value, error)元组,但这有点麻烦。我们可以有任意多的参数,我们可以用这些。

So, methods/functions can't modify their parameters (to be precise, they operate with a copy, so any modifications they make are local). That is to say (concurrency issues aside) the value of fetchRequest before the message in your question will be equal to the value of fetchRequest afterwards. Note the object pointed to by fetchRequest might change, but the value of fetchRequest itself won't.

因此,方法/函数不能修改它们的参数(准确地说,它们使用一个副本进行操作,所以它们所做的任何修改都是本地的)。也就是说(除了并发问题)问题中的消息之前的fetchRequest的值将等于之后的fetchRequest的值。注意,fetchRequest指向的对象可能会改变,但fetchRequest本身的值不会改变。

This puts us in a bit of a bind. Except, wait, we know we can happily take the value of a parameter and modify what it points to! If you look at the declaration for executeFetchRequest:error: you'll see it takes an NSError**. That's "a pointer to a pointer to an NSError". So, we can initialise an empty/dangling NSError*, find the address of it (with the unary & operator), and pass that in. The method can then assign to the NSError* pointed to by this.

这让我们有点为难。除了,等等,我们知道我们可以很高兴地获取参数的值并修改它指向的内容!如果查看executeFetchRequest的声明:error:您将看到它带有一个NSError*。这是指向NSError指针的指针。因此,我们可以初始化一个空的/悬浮的NSError*,找到它的地址(使用一元和运算符),并将其传递进去。然后该方法可以赋值给由它指向的NSError*。

Voila, we effectively have optional additional return values.

瞧,我们实际上有可选的附加返回值。

#1


57  

You need to take the address of error because the function needs to modify it. error is passed by pointer, so you need the "take address" operator & for it.

您需要获取错误地址,因为函数需要修改它。错误是通过指针传递的,所以需要使用“take address”操作符。

C and Objective-C pass parameters by value. If you pass error without an ampersand and the method that you call modifies it, your function that made the call would not see any changes, because the method would operate on its local copy of NSError*.

C和Objective-C按值传递参数。如果您传递的错误没有符号,并且您调用的方法修改了它,那么进行调用的函数将不会看到任何更改,因为该方法将对其NSError*的本地副本进行操作。

You know that you need an ampersand in front of the corresponding parameter if you look at the signature of the method and see ** there:

如果您查看方法的签名并在那里看到**,您就知道需要在相应的参数前面加上一个&号:

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

#2


7  

The error parameter's type is (NSError **), that is a pointer to a pointer to an NSError. The error variable that you use as the argument is probably declared as NSError *, so in order to get the types to match properly, you have to use the address of operator to get a pointer to a pointer (&error). The reason the method needs a pointer to a pointer in the first place is so that it can modify the value of error and have that new value be available to you, the caller of the method.

错误参数的类型是(NSError **),它是指向NSError的指针。作为参数使用的错误变量可能被声明为NSError *,因此为了使类型正确匹配,您必须使用操作符的地址来获取指向指针的指针(和错误)。这个方法首先需要一个指针指向一个指针,这样它就可以修改错误的值,并让这个方法的调用者可以获得新的值。

#3


6  

Essentially, the root of the issue is a hack for wanting to return a second (optional) object.

本质上,这个问题的根源是想要返回第二个(可选)对象的hack。

How can we do this, as we can only return one thing? Well, we could return some sort of (return_value, error) tuple, but that's a bit unwieldy. We can have as many parameters as we like though, can we do something with those...

我们怎么做呢,因为我们只能返回一件东西?我们可以返回某种(return_value, error)元组,但这有点麻烦。我们可以有任意多的参数,我们可以用这些。

So, methods/functions can't modify their parameters (to be precise, they operate with a copy, so any modifications they make are local). That is to say (concurrency issues aside) the value of fetchRequest before the message in your question will be equal to the value of fetchRequest afterwards. Note the object pointed to by fetchRequest might change, but the value of fetchRequest itself won't.

因此,方法/函数不能修改它们的参数(准确地说,它们使用一个副本进行操作,所以它们所做的任何修改都是本地的)。也就是说(除了并发问题)问题中的消息之前的fetchRequest的值将等于之后的fetchRequest的值。注意,fetchRequest指向的对象可能会改变,但fetchRequest本身的值不会改变。

This puts us in a bit of a bind. Except, wait, we know we can happily take the value of a parameter and modify what it points to! If you look at the declaration for executeFetchRequest:error: you'll see it takes an NSError**. That's "a pointer to a pointer to an NSError". So, we can initialise an empty/dangling NSError*, find the address of it (with the unary & operator), and pass that in. The method can then assign to the NSError* pointed to by this.

这让我们有点为难。除了,等等,我们知道我们可以很高兴地获取参数的值并修改它指向的内容!如果查看executeFetchRequest的声明:error:您将看到它带有一个NSError*。这是指向NSError指针的指针。因此,我们可以初始化一个空的/悬浮的NSError*,找到它的地址(使用一元和运算符),并将其传递进去。然后该方法可以赋值给由它指向的NSError*。

Voila, we effectively have optional additional return values.

瞧,我们实际上有可选的附加返回值。