问题描述
为什么这里使用错误:&错误(objective-c)
why is "error:&error" used here (objective-c)
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
无论如何,objective-c中的对象不会被有效传递吗?
wouldn't an object in objective-c be effectively pass-by-reference anyway?
推荐答案
错误的参数类型:
是 NSError * *
(即指向对象的指针的指针)。这允许 moc
对象根据需要分配和初始化新的 NSError
对象。这是一种常见的模式,特别是在Cocoa中。
The argument type for error:
is NSError**
(i.e. a pointer to a pointer to an object). This permits the moc
object to allocate and initialize a new NSError
object as required. It is a common pattern, especially in Cocoa.
给出了这种方法动机的一些指示:
The NSError documentation gives some indication of the motivation for this approach:
传入 NSError **
参数允许该方法返回 NSError的任何子类
这就说得通了。如果您传入 NSError *
,则必须提供现有的 NSError
对象,并且无法使用从传入的对象中返回不同对象的方法。
Passing in an NSError**
argument allows that method to return any subclass of NSError
that makes sense. If you passed in NSError*
, you would have to supply an existing NSError
object, and there would be no way for the method to return a different object from the one you passed in.
要清楚,方法可能如下所示:
To be clear, the method could look something like this:
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError**)error {
...
if ((error != NULL) && (some_error_condition)) {
*error = [[[SomeNSErrorSubclass alloc] init...] autorelease];
return nil;
}
}
请注意,这也允许调用代码忽略错误只需传入 NULL
获取错误:
参数,如下所示:
Note that this also allows the calling code to ignore errors by simply passing in NULL
for the error:
parameter, as follows:
NSArray *array = [moc executeFetchRequest:request error:NULL];
更新: (回答问题) ):
Update: (in response to questions):
为什么参数类型必须是 NSError **
而不是 NSError *
:1。变量范围规则,以及2. NSError实例是不可变的。
There are two reasons why the argument type has to be NSError**
instead of NSError*
: 1. variable scoping rules, and 2. NSError instances are imutable.
原因#1:变量范围规则
我们假设函数声明如下所示:
Let's assume that the function declaration were to look like this:
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error;
我们要调用这样的函数:
And we were to call the function like this:
NSError * error = nil;
[someArray executeFetchRequest:someRequest error:error];
if (error != nil) { /* handle error */ }
当你以这种方式传递变量,函数体将无法修改该变量的值(即函数体将无法创建新变量来替换现有变量)。例如,以下变量赋值仅存在于函数的局部范围内。调用代码仍然会看到错误== nil
。
When you pass in a variable this way, the function body will not be able to modify the value of that variable (i.e. the function body will not be able to create a new variable to replace the existing one). For example, the following variable assignments will exist only in the local scope of the function. The calling code will still see error == nil
.
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error {
...
error = [[[NSError alloc] init...] autorelease]; // local only
error = [[[SomeNSErrorSubclass alloc] init...] autorelease]; // local only
}
原因#2:NSError的实例是不可变的
让我们保持相同的函数声明,但是调用这样的函数:
Let's keep the same function declaration, but call the function like this:
NSError * error = [[[NSError alloc] init...] autorelease];
[someArray executeFetchRequest:someRequest error:error];
if (error != nil) { /* handle error */ }
首先所有,变量范围规则保证错误
不能 nil
,所以 if( error!= nil){...
条件将始终为true,但即使您要检查 if
块内的特定错误信息,你会失败,因为 NSError
的实例是不可变的。这意味着一旦创建它们,您就无法修改它们的属性,因此该函数将无法更改域
或 userInfo $ c您在调用代码中创建的
NSError
实例的$ c>。
First of all, the variable scoping rules guarantee that error
can not be nil
, so the if (error != nil) { ...
condition will always be true, but even if you wanted to check for specific error information inside the if
block, you would be out of luck because instances of NSError
are immutable. This means that once they are created, you cannot modify their properties, so the function would not be able to change the domain
or userInfo
of that NSError
instance that you created in the calling code.
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error {
...
error.domain = ... // not allowed!
error.userInfo = ... // not allowed!
}
这篇关于为什么是“错误:&错误”在这里使用(objective-c)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!