为什么在这里使用“error:&error”(objective-c)
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
无论如何,objective-c 中的对象不会有效地通过引用传递吗?
为什么在这里使用“error:&error”(objective-c)
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
无论如何,objective-c 中的对象不会有效地通过引用传递吗?
的参数类型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;
}
}
请注意,这还允许调用代码通过简单地传入参数来忽略错误NULL
,error:
如下所示:
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 */ }
首先,变量作用域规则保证error
can not be nil
,所以if (error != nil) { ...
条件总是为真,但是即使你想检查if
块内的特定错误信息,你也会很不幸,因为实例NSError
是不可变的。这意味着一旦创建它们,您就无法修改它们的属性,因此该函数将无法更改您在调用代码中创建的那个实例的domain
or 。userInfo
NSError
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error {
...
error.domain = ... // not allowed!
error.userInfo = ... // not allowed!
}
它实际上是另一个返回值。当操作有返回值时,错误在 Cocoa 中并不占主导地位。当遇到错误时,可能会通过这个 out 参数返回给你。
在 的情况下NSError
,它以这种方式工作,因为NSError
它不是可变类型 - 它的字段在初始化时设置并且从不变异。因此,您不能NSError
像往常一样传递并设置错误代码。