35

我想知道,为什么我们在下面这样的 NSError 前面放置:&error而不是error

例如

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

希望您能解释一下,这是否总是这样或仅在某些情况下才需要?谢谢。

4

3 回答 3

63

您需要获取地址,error因为函数需要对其进行修改。由指针error传递,因此您需要“获取地址”运算符。&

C 和 Objective-C按值传递参数。如果您在error没有与号的情况下通过并且您调用的方法对其进行了修改,则进行调用的函数将看不到任何更改,因为该方法将在其本地副本上运行NSError*.

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

- (NSArray *)executeFetchRequest:(NSFetchRequest *)request error:(NSError **)error
                                            //   ^ one                    ^^ two
于 2012-04-07T23:24:03.753 回答
8

参数的error类型是(NSError **),即指向 NSError 的指针。error您用作参数的变量可能声明为,NSError *因此为了使类型正确匹配,您必须使用运算符的地址来获取指向指针 ( &error) 的指针。该方法首先需要一个指向指针的指针的原因是它可以修改 的值error并使该新值可供您(该方法的调用者)使用。

于 2012-04-07T23:26:54.697 回答
7

从本质上讲,问题的根源是想要返回第二个(可选)对象的黑客攻击。

我们怎么能做到这一点,因为我们只能返回一件事?好吧,我们可以返回某种(return_value, error)元组,但这有点笨拙。不过,我们可以有尽可能多的参数,我们可以对这些参数做些什么......

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

这让我们有点束手无策。除了,等等,我们知道我们可以愉快地获取参数的值并修改它所指向的内容!如果您查看声明,executeFetchRequest:error:您会发现它需要一个NSError**. 那是“指向指向“的指针的指针NSError。因此,我们可以初始化一个空/悬空NSError*,找到它的地址(使用一元运算&),然后将其传入。然后该方法可以分配给NSError*this 指向的指针。

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

于 2012-04-07T23:33:59.277 回答