8

为什么在这里使用“error:&error”(objective-c)

NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];

无论如何,objective-c 中的对象不会有效地通过引用传递吗?

4

2 回答 2

22

的参数类型error:NSError**(即指向对象指针的指针)。这允许moc对象根据需要分配和初始化一个新NSError对象。这是一种常见的模式,尤其是在 Cocoa 中。

NSError 文档给出了这种方法的动机:

应用程序可以选择创建 NSError 的子类,以通过覆盖本地化描述来提供更好的本地化错误字符串。

传入一个NSError**参数允许该方法返回任何NSError有意义的子类。如果您传入NSError*,则必须提供一个现有NSError对象,并且该方法无法返回与您传入的对象不同的对象。

需要明确的是,该方法可能如下所示:

- (NSArray*)executeFetchRequest:(Request *)request error:(NSError**)error {
    ...
    if ((error != NULL) && (some_error_condition)) {
        *error = [[[SomeNSErrorSubclass alloc] init...] autorelease];
        return nil;
    }
}

请注意,这还允许调用代码通过简单地传入参数来忽略错误NULLerror:如下所示:

NSArray *array = [moc executeFetchRequest:request error:NULL];

更新:(回答问题):

NSError**参数类型必须代替的原因有两个NSError*:1. 变量范围规则,以及 2. NSError 实例是不可变的。

原因 #1:变量范围规则

假设函数声明如下所示:

- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error;

我们要这样调用函数:

NSError * error = nil;
[someArray executeFetchRequest:someRequest error:error];
if (error != nil) { /* handle error */ }

当您以这种方式传入变量时,函数体将无法修改该变量的(即函数体将无法创建新变量来替换现有变量)。例如,以下变量赋值将仅存在于函数的局部范围内。调用代码仍会看到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 的实例是不可变的

让我们保持相同的函数声明,但像这样调用函数:

NSError * error = [[[NSError alloc] init...] autorelease];
[someArray executeFetchRequest:someRequest error:error];
if (error != nil) { /* handle error */ }

首先,变量作用域规则保证errorcan not be nil,所以if (error != nil) { ...条件总是为真,但是即使你想检查if块内的特定错误信息,你也会很不幸,因为实例NSError不可变的。这意味着一旦创建它们,您就无法修改它们的属性,因此该函数将无法更改您在调用代码中创建的那个实例的domainor 。userInfoNSError

- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error {
    ...
    error.domain = ...   // not allowed!
    error.userInfo = ... // not allowed!
}
于 2011-11-30T23:34:29.160 回答
3

它实际上是另一个返回值。当操作有返回值时,错误在 Cocoa 中并不占主导地位。当遇到错误时,可能会通过这个 out 参数返回给你。

在 的情况下NSError,它以这种方式工作,因为NSError不是可变类型 - 它的字段在初始化时设置并且从不变异。因此,您不能NSError像往常一样传递并设置错误代码。

于 2011-11-30T23:41:59.707 回答